+bool AndCondition::merge(const AndCondition &cond1, const AndCondition &cond2, const CompoundCondition &parent, AndCondition **result)
+{
+ if(cond1.count()!=cond2.count())
+ return false;
+
+ int merge1 = -1;
+ vector<bool> used(cond1.count(), false);
+ for(unsigned i=0; i<cond1.count(); ++i)
+ {
+ int match = -1;
+ for(unsigned j=0; (match<0 && j<cond2.count()); ++j)
+ if(!used[j] && cond1.get(i).equals(cond2.get(j)))
+ match = j;
+
+ if(match>=0)
+ used[match] = true;
+ else if(merge1<0)
+ merge1 = i;
+ else
+ return false;
+ }
+
+ if(merge1>=0)
+ {
+ vector<const Condition *> merge_conds(2, 0);
+ merge_conds[0] = &cond1.get(merge1);
+ for(unsigned i=0; (!merge_conds[1] && i<cond2.count()); ++i)
+ if(!used[i])
+ merge_conds[1] = &cond2.get(i);
+
+ if(!merge_conds[1] || !merge_conds[0]->can_merge(*merge_conds[1], parent))
+ return false;
+
+ if(result)
+ {
+ *result = new AndCondition;
+ (*result)->add(merge_conds[0]->merge(merge_conds, parent));
+ }
+ }
+ else if(result)
+ *result = new AndCondition;
+
+ if(result)
+ {
+ for(unsigned i=0; i<cond2.count(); ++i)
+ if(used[i])
+ (*result)->add(cond2.get(i).clone());
+ }
+
+ return true;
+}
+
+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();
+}
+