throw new IllegalArgumentException("Cannot divide by 0. Dividend: " + this);
}
NavigableMap<NaturalNumber, Expression> q = new TreeMap(); // quotient
NavigableMap<NaturalNumber, Expression> r = new TreeMap(); // reminder
NaturalNumber bdeg = b.degree();
Expression bc = b.leadCoefficient();
Expression c; // next coefficient
NaturalNumber n; // degree of the next term in q
Expression rp, bi; // temporary variables
NaturalNumber p; //temporary position
q.put(ZERO, ZERO);
r.putAll(this.coeffs);
while (!isZero(r) && bdeg.le(r.lastKey())) {
c = new Division(r.lastEntry().getValue(), bc).evaluate();
n = (NaturalNumber) r.lastKey().subtract(bdeg);
q.put(n, c);
for (NaturalNumber i : b.coeffs.descendingKeySet()) {
p = (NaturalNumber) n.add(i);
rp = r.get(p);
bi = b.coeffs.get(i);
rp = rp != null ? new Subtraction(rp, new Multiplication(c, bi)).evaluate()
: new Negation(new Multiplication(c, bi)).evaluate();
if (rp instanceof ANumber && ((ANumber) rp).isZero() && !p.isZero()) {
r.remove(p);
} else {
r.put(p, rp);
}
}