+ epvector distrseq;
+ distrseq.reserve(addref.seq.size());
+ for (auto & it : addref.seq) {
+ distrseq.push_back(addref.combine_pair_with_coeff_to_pair(it, overall_coeff));
+ }
+ return dynallocate<add>(std::move(distrseq),
+ ex_to<numeric>(addref.overall_coeff).mul_dyn(ex_to<numeric>(overall_coeff)))
+ .setflag(status_flags::evaluated);
+ } else if ((seq_size >= 2) && (! (flags & status_flags::expanded))) {
+ // Strip the content and the unit part from each term. Thus
+ // things like (-x+a)*(3*x-3*a) automagically turn into - 3*(x-a)^2
+
+ auto i = seq.begin(), last = seq.end();
+ auto j = seq.begin();
+ epvector s;
+ numeric oc = *_num1_p;
+ bool something_changed = false;
+ while (i!=last) {
+ if (likely(! (is_a<add>(i->rest) && i->coeff.is_equal(_ex1)))) {
+ // power::eval has such a rule, no need to handle powers here
+ ++i;
+ continue;
+ }
+
+ // XXX: What is the best way to check if the polynomial is a primitive?
+ numeric c = i->rest.integer_content();
+ const numeric lead_coeff =
+ ex_to<numeric>(ex_to<add>(i->rest).seq.begin()->coeff).div(c);
+ const bool canonicalizable = lead_coeff.is_integer();
+
+ // XXX: The main variable is chosen in a random way, so this code
+ // does NOT transform the term into the canonical form (thus, in some
+ // very unlucky event it can even loop forever). Hopefully the main
+ // variable will be the same for all terms in *this
+ const bool unit_normal = lead_coeff.is_pos_integer();
+ if (likely((c == *_num1_p) && ((! canonicalizable) || unit_normal))) {
+ ++i;
+ continue;
+ }
+
+ if (! something_changed) {
+ s.reserve(seq_size);
+ something_changed = true;
+ }
+
+ while ((j!=i) && (j!=last)) {
+ s.push_back(*j);
+ ++j;
+ }
+
+ if (! unit_normal)
+ c = c.mul(*_num_1_p);
+
+ oc = oc.mul(c);
+
+ // divide add by the number in place to save at least 2 .eval() calls
+ const add& addref = ex_to<add>(i->rest);
+ add & primitive = dynallocate<add>(addref);
+ primitive.clearflag(status_flags::hash_calculated);
+ primitive.overall_coeff = ex_to<numeric>(primitive.overall_coeff).div_dyn(c);
+ for (auto & ai : primitive.seq)
+ ai.coeff = ex_to<numeric>(ai.coeff).div_dyn(c);
+
+ s.push_back(expair(primitive, _ex1));
+