private Type parse(String sig) {
        this.sig = sig;
        sigp = 0;

        List<TypeParamType> typeParamTypes = null;
        if (sig.charAt(sigp) == '<')
            typeParamTypes = parseTypeParamTypes();

        if (sig.charAt(sigp) == '(') {
            List<Type> paramTypes = parseTypeSignatures(')');
            Type returnType = parseTypeSignature();
            List<Type> throwsTypes = null;
            while (sigp < sig.length() && sig.charAt(sigp) == '^') {
                sigp++;
                if (throwsTypes == null)
                    throwsTypes = new ArrayList<Type>();
                throwsTypes.add(parseTypeSignature());
            }
            return new MethodType(typeParamTypes, paramTypes, returnType, throwsTypes);
        } else {
            Type t = parseTypeSignature();
            if (typeParamTypes == null && sigp == sig.length())
                return t;
            Type superclass = t;
            List<Type> superinterfaces = null;
            while (sigp < sig.length()) {
                if (superinterfaces == null)
                    superinterfaces = new ArrayList<Type>();
                superinterfaces.add(parseTypeSignature());
            }
            return new ClassSigType(typeParamTypes, superclass, superinterfaces);

        }
    }