private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
        List<Type> fromArgs = from.type.getParameterTypes();
        List<Type> toArgs = to.type.getParameterTypes();
        if (useVarargs &&
                (from.flags() & VARARGS) != 0 &&
                (to.flags() & VARARGS) != 0) {
            Type varargsTypeFrom = fromArgs.last();
            Type varargsTypeTo = toArgs.last();
            ListBuffer<Type> args = ListBuffer.lb();
            if (toArgs.length() < fromArgs.length()) {
                //if we are checking a varargs method 'from' against another varargs
                //method 'to' (where arity of 'to' < arity of 'from') then expand signature
                //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
                //until 'to' signature has the same arity as 'from')
                while (fromArgs.head != varargsTypeFrom) {
                    args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
                    fromArgs = fromArgs.tail;
                    toArgs = toArgs.head == varargsTypeTo ?
                        toArgs :
                        toArgs.tail;
                }
            } else {
                //formal argument list is same as original list where last
                //argument (array type) is removed
                args.appendList(toArgs.reverse().tail.reverse());
            }
            //append varargs element type as last synthetic formal
            args.append(types.elemtype(varargsTypeTo));
            Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
            return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
        } else {
            return to;
        }
    }