Type rewrite(Type t) {
            ListBuffer<Type> from = new ListBuffer<Type>();
            ListBuffer<Type> to = new ListBuffer<Type>();
            adaptSelf(t, from, to);
            ListBuffer<Type> rewritten = new ListBuffer<Type>();
            List<Type> formals = from.toList();
            boolean changed = false;
            for (Type arg : to.toList()) {
                Type bound = visit(arg);
                if (arg != bound) {
                    changed = true;
                    bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
                              : makeSuperWildcard(bound, (TypeVar)formals.head);
                }
                rewritten.append(bound);
                formals = formals.tail;
            }
            if (changed)
                return subst(t.tsym.type, from.toList(), rewritten.toList());
            else
                return t;
        }