+bool AndCondition::equals(const Condition &other) const
+{
+ const AndCondition *other_and = dynamic_cast<const AndCondition *>(&other);
+ return (other_and ? sub_equals(*other_and) : false);
+}
+
+Condition *AndCondition::flatten(Condition *cond1, Condition *cond2) const
+{
+ if(cond1->can_merge(*cond2, *this))
+ return merge_two(cond1, cond2, *this, true);
+
+ AndCondition *result = new AndCondition;
+ result->add(cond1);
+ result->add(cond2);
+ return result;
+}
+
+Condition *AndCondition::flatten(AndCondition *cond1, Condition *cond2) const
+{
+ return add_merged_to(cond2, cond1, true);
+}
+
+Condition *AndCondition::flatten(AndCondition *cond1, AndCondition *cond2) const
+{
+ return merge_contents_to(cond2, cond1);
+}
+
+Condition *AndCondition::flatten(OrCondition *cond1, Condition *cond2) const
+{
+ OrCondition *result = new OrCondition;
+ unsigned count = cond1->count();
+ for(unsigned i=0; i<count; ++i)
+ if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), (i+1<count ? cond2->clone() : cond2)))
+ result->add(sub);
+ delete cond1;
+
+ if(result->is_viable())
+ return result;
+
+ delete result;
+ return 0;
+}
+
+Condition *AndCondition::flatten(OrCondition *cond1, AndCondition *cond2) const
+{
+ return flatten(cond1, static_cast<Condition *>(cond2));
+}
+
+Condition *AndCondition::flatten(OrCondition *cond1, OrCondition *cond2) const
+{
+ unsigned count1 = cond1->count();
+ unsigned count2 = cond2->count();
+ OrCondition *result = new OrCondition;
+ for(unsigned i=0; i<count1; ++i)
+ for(unsigned j=0; j<count2; ++j)
+ if(Condition *sub = dispatch_flatten(cond1->get(i).clone(), cond2->get(j).clone()))
+ result->add(sub);
+
+ delete cond1;
+ delete cond2;
+
+ if(result->is_viable())
+ return result;
+
+ delete result;
+ return 0;
+}
+
+bool AndCondition::is_viable() const
+{
+ for(vector<Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
+ if(!(*i)->is_viable())
+ return false;
+ return !conditions.empty();
+}
+