'(a*b)**n -> a**n * b**n'

def _eval_expand_power_base(self, **hints):

    force = hints.get('force', False)
    b = self.base
    e = self.exp
    if (not b.is_Mul):
        return self
    (cargs, nc) = b.args_cnc(split_1=False)
    if nc:
        nc = [(i._eval_expand_power_base(**hints) if hasattr(i, '_eval_expand_power_base') else i) for i in nc]
        if e.is_Integer:
            if e.is_positive:
                rv = Mul(*(nc * e))
            else:
                rv = (1 / Mul(*(nc * (- e))))
            if cargs:
                rv *= (Mul(*cargs) ** e)
            return rv
        if (not cargs):
            return self.func(Mul(*nc), e, evaluate=False)
        nc = [Mul(*nc)]
    sifted = sift(cargs, (lambda x: x.is_real))
    maybe_real = (sifted[True] + sifted[None])
    other = sifted[False]
    def pred(x):
        if (x is S.ImaginaryUnit):
            return S.ImaginaryUnit
        polar = x.is_polar
        if polar:
            return True
        if (polar is None):
            return fuzzy_bool(x.is_nonnegative)
    sifted = sift(maybe_real, pred)
    nonneg = sifted[True]
    other += sifted[None]
    neg = sifted[False]
    imag = sifted[S.ImaginaryUnit]
    if imag:
        I = S.ImaginaryUnit
        i = (len(imag) % 4)
        if (i == 0):
            pass
        elif (i == 1):
            other.append(I)
        elif (i == 2):
            if neg:
                nonn = (- neg.pop())
                if (nonn is not S.One):
                    nonneg.append(nonn)
            else:
                neg.append(S.NegativeOne)
        else:
            if neg:
                nonn = (- neg.pop())
                if (nonn is not S.One):
                    nonneg.append(nonn)
            else:
                neg.append(S.NegativeOne)
            other.append(I)
        del imag
    if (force or e.is_integer):
        cargs = ((nonneg + neg) + other)
        other = nc
    else:
        assert (not e.is_Integer)
        if (len(neg) > 1):
            o = S.One
            if ((not other) and neg[0].is_Number):
                o *= neg.pop(0)
            if (len(neg) % 2):
                o = (- o)
            for n in neg:
                nonneg.append((- n))
            if (o is not S.One):
                other.append(o)
        elif (neg and other):
            if (neg[0].is_Number and (neg[0] is not S.NegativeOne)):
                other.append(S.NegativeOne)
                nonneg.append((- neg[0]))
            else:
                other.extend(neg)
        else:
            other.extend(neg)
        del neg
        cargs = nonneg
        other += nc
    rv = S.One
    if cargs:
        rv *= Mul(*[self.func(b, e, evaluate=False) for b in cargs])
    if other:
        rv *= self.func(Mul(*other), e, evaluate=False)
    return rv
