'Takes the sequence "seq" of nested Adds and returns a flatten list.
Returns: (commutative_part, noncommutative_part, order_symbols)
Applies associativity, all terms are commutable with respect to
addition.
NB: the removal of 0 is already handled by AssocOp.__new__
See also
sympy.core.mul.Mul.flatten'

@classmethod
def flatten(cls, seq):

    from sympy.calculus.util import AccumBounds
    from sympy.matrices.expressions import MatrixExpr
    rv = None
    if (len(seq) == 2):
        (a, b) = seq
        if b.is_Rational:
            (a, b) = (b, a)
        if a.is_Rational:
            if b.is_Mul:
                rv = ([a, b], [], None)
        if rv:
            if all((s.is_commutative for s in rv[0])):
                return rv
            return ([], rv[0], None)
    terms = {}
    coeff = S.Zero
    order_factors = []
    for o in seq:
        if o.is_Order:
            for o1 in order_factors:
                if o1.contains(o):
                    o = None
                    break
            if (o is None):
                continue
            order_factors = ([o] + [o1 for o1 in order_factors if (not o.contains(o1))])
            continue
        elif o.is_Number:
            if ((o is S.NaN) or ((coeff is S.ComplexInfinity) and (o.is_finite is False))):
                return ([S.NaN], [], None)
            if coeff.is_Number:
                coeff += o
                if (coeff is S.NaN):
                    return ([S.NaN], [], None)
            continue
        elif isinstance(o, AccumBounds):
            coeff = o.__add__(coeff)
            continue
        elif isinstance(o, MatrixExpr):
            coeff = o.__add__(coeff)
            continue
        elif (o is S.ComplexInfinity):
            if (coeff.is_finite is False):
                return ([S.NaN], [], None)
            coeff = S.ComplexInfinity
            continue
        elif o.is_Add:
            seq.extend(o.args)
            continue
        elif o.is_Mul:
            (c, s) = o.as_coeff_Mul()
        elif o.is_Pow:
            (b, e) = o.as_base_exp()
            if (b.is_Number and (e.is_Integer or (e.is_Rational and e.is_negative))):
                seq.append((b ** e))
                continue
            (c, s) = (S.One, o)
        else:
            c = S.One
            s = o
        if (s in terms):
            terms[s] += c
            if (terms[s] is S.NaN):
                return ([S.NaN], [], None)
        else:
            terms[s] = c
    newseq = []
    noncommutative = False
    for (s, c) in terms.items():
        if (c is S.Zero):
            continue
        elif (c is S.One):
            newseq.append(s)
        elif s.is_Mul:
            cs = s._new_rawargs(*((c,) + s.args))
            newseq.append(cs)
        elif s.is_Add:
            newseq.append(Mul(c, s, evaluate=False))
        else:
            newseq.append(Mul(c, s))
        noncommutative = (noncommutative or (not s.is_commutative))
    if (coeff is S.Infinity):
        newseq = [f for f in newseq if (not (f.is_nonnegative or (f.is_real and f.is_finite)))]
    elif (coeff is S.NegativeInfinity):
        newseq = [f for f in newseq if (not (f.is_nonpositive or (f.is_real and f.is_finite)))]
    if (coeff is S.ComplexInfinity):
        newseq = [c for c in newseq if (not (c.is_finite and (c.is_real is not None)))]
    if order_factors:
        newseq2 = []
        for t in newseq:
            for o in order_factors:
                if o.contains(t):
                    t = None
                    break
            if (t is not None):
                newseq2.append(t)
        newseq = (newseq2 + order_factors)
        for o in order_factors:
            if o.contains(coeff):
                coeff = S.Zero
                break
    _addsort(newseq)
    if (coeff is not S.Zero):
        newseq.insert(0, coeff)
    if noncommutative:
        return ([], newseq, None)
    else:
        return (newseq, [], None)
