In response to a question about collecting symbolic powers of polynomials, I suggested a few lines of code that solved the particular problem. Following is a procedure that enhances the technique to mimic, to some degree, the abilities of Maple's collect procedure, which handles integral powers. This enhanced version can take a list of indeterminates. It also permits use of an optional third argument, func, that is applied to the collected coefficients of a power.
collectsymbolic := proc(a, x, func::{identical(NULL),name} := NULL)
local poly,f,xvar;
    poly := combine(a, 'power');
    poly := collect(poly, x, func);
    xvar := `if`(x::{list,set},op(x),x);
    poly := subsindets(poly
                       , identical(xvar)^(Not(integer))
                       , () -> f(op(args)));
    poly := collect(poly, f, func);
    eval(poly, f=`^`);
end proc:
poly := a*x^p + a^2*x*x^(p-1) + b*y*y^q + c*y^(q+1):
collectsymbolic( poly, [x,y] );
                              2   p            (q + 1)
                        (a + a ) x  + (b + c) y

collectsymbolic( poly, [x,y], factor );
                                   p            (q + 1)
                        a (1 + a) x  + (b + c) y

Please Wait...