public ArrayList<Polynomial> factor(int maxdegree) throws Exception {
        // zero
        if (coeff.length == 0) {
            ArrayList<Polynomial> factors = new ArrayList<Polynomial>();
            factors.add(zero());
            return factors;
        }
    
        // constants
        if (coeff.length == 1) {
            ArrayList<Polynomial> factors = new ArrayList<Polynomial>();
            factors.add(constant(coeff[0]));
            return factors;
        }
    
        // linear terms
        if (coeff.length == 2) {
            ArrayList<Polynomial> factors = new ArrayList<Polynomial>();
            if (coeff[1] == 1L) {
                factors.add(this);
            } else {
                factors.add(constant(coeff[1]));
                factors.add(monic());
            }
            return factors;
        }
    
        // call factor2 with a monic polynomial of degree >= 2.
        if (head() == 1L) {
            return factor2(maxdegree);
        } else {
            ArrayList<Polynomial> factors = monic().factor2(maxdegree);
            factors.add(constant(head()));
            return factors;
        }
    }