classMembers.enter(ifaceMemberSym);
classMembers.enterOrOverload(ifaceMemberSym);
        public void traverse(Tree tree) {            switch(tree) {            case ClassDef(_, _, _, _, _, Template impl): {                Symbol ifaceSym = tree.symbol();                if (!needInterface(ifaceSym)) {                    super.traverse(impl);                    break;                }                // The class needs an interface. Create new symbols                // for the class itself, its constructor, its type                // parameters and its members. Then modify what was                // the class symbol to turn it into an interface                // symbol.                // At the end of this part, one inconsistency remains:                // the base types of the new class symbols still refer                // to interface symbols. This is fixed later, when                // symbols exist for *all* classes.                Symbol ifaceConstrSym = ifaceSym.constructor();                ifaceConstrSym.updateInfo(removeValueParams(ifaceConstrSym.info()));                if (! ifaceToClass.containsKey(ifaceSym))                    makeClassSymbol(ifaceSym);                Symbol classSym = (Symbol)ifaceToClass.get(ifaceSym);                Symbol classConstrSym = classSym.constructor();                if (ifaceToClass.containsKey(classSym.owner())) {                    Symbol newOwner = (Symbol)ifaceToClass.get(classSym.owner());                    classSym.setOwner(newOwner);                    classConstrSym.setOwner(newOwner);                }                Symbol[] ifaceTParams = ifaceSym.typeParams();                if (ifaceTParams.length > 0) {                    for (int i = 0; i < ifaceTParams.length; ++i) {                        Symbol classTParam = ifaceTParams[i].cloneSymbol();                        classTParam.setOwner(classConstrSym);                        tparamsMap.put(ifaceTParams[i], classTParam);                    }                }                assert !typeParamsMaps.containsKey(classSym);                Map cloneMap = new HashMap();                cloneMap.putAll(tparamsMap);                typeParamsMaps.put(classSym, cloneMap);                SymbolMapApplier tparamsSM = new SymbolMapApplier(cloneMap);                classConstrSym.setInfo(tparamsSM.apply(classConstrSym.info()));                Symbol[] vparams = vparams(classConstrSym.nextInfo());                for (int i = 0; i < vparams.length; ++i) {                    vparams[i].setOwner(classConstrSym);                    vparams[i].updateInfo(tparamsSM.apply(vparams[i].info()));                }                Scope newIFaceMembers = new Scope();                Scope classMembers = new Scope();                Scope.SymbolIterator symIt = ifaceSym.members().iterator();                while (symIt.hasNext()) {                    Symbol ifaceMemberSym = symIt.next();                    ifaceMemberSym.updateInfo(tparamsSM.apply(ifaceMemberSym.info()));                    if (! memberGoesInInterface(ifaceMemberSym)) {                        ifaceMemberSym.setOwner(classSym);                        classMembers.enter(ifaceMemberSym);                        continue;                    }                    // When encountering a constructor of a nested                    // class, clone its class to make sure the                    // constructor is cloned correctly.                    if (ifaceMemberSym.isPrimaryConstructor()                        && !ifaceToClass.containsKey(ifaceMemberSym)) {                        makeClassSymbol(ifaceMemberSym.primaryConstructorClass());                    }                    // Make private members public and give them a                    // unique name.                    if (Modifiers.Helper.isPrivate(ifaceMemberSym.flags)) {                        ifaceMemberSym.name = uniqueName(ifaceMemberSym);                        ifaceMemberSym.flags ^= Modifiers.PRIVATE;                    }                    ifaceMemberSym.flags &= ~Modifiers.PROTECTED;                    newIFaceMembers.enter(ifaceMemberSym);                    // Type members are moved to the interface.                    // Therefore, no symbol has to be created for                    // their class equivalent.                    if (ifaceMemberSym.kind == Kinds.TYPE                        || ifaceMemberSym.kind == Kinds.ALIAS)                        continue;                    Symbol[] alternatives = ifaceMemberSym.alternatives();                    Symbol classMemberSym = null;                    for (int a = 0; a < alternatives.length; ++a) {                        Symbol iSym = alternatives[a];                        Symbol cSym;                        if (Modifiers.Helper.isPrivate(iSym.flags)) {                            iSym.name = uniqueName(iSym);                            iSym.flags ^= Modifiers.PRIVATE;                        }                        iSym.flags &= ~Modifiers.PROTECTED;                        if (ifaceToClass.containsKey(iSym))                            cSym = (Symbol)ifaceToClass.get(iSym);                        else                            cSym = cloneAndMaybeRenameSymbol(iSym);                        iSym.updateInfo(tparamsSM.apply(iSym.info()));                        cSym.setInfo(tparamsSM.apply(cSym.info()));                        Symbol[] vpms = vparams(iSym.nextInfo());                        for (int p = 0; p < vpms.length; ++p)                            vpms[p].updateInfo(tparamsSM.apply(vpms[p].info()));                        // Clone parameter symbols for methods.                        if (cSym.isMethod()) {                            Map funSymMap = new HashMap();                            Type newInfo = cloneSymbolsInMethodType(cSym.info(),                                                                    cSym,                                                                    tparamsSM,                                                                    funSymMap);                            if (! funSymMap.isEmpty())                                funParamsMaps.put(cSym, funSymMap);                        }                        cSym.setOwner(classSym);                        classMemberSym = (classMemberSym == null                                          ? cSym                                          : classMemberSym.overloadWith(cSym));                        if (iSym.kind == Kinds.CLASS) {                            ifaceToClass.put(iSym, cSym);                            ifaceToClass.put(iSym.constructor(), cSym.constructor());                        } else {                            iSym.flags |= Modifiers.DEFERRED;                            ifaceMemberToClass.put(iSym, cSym);                        }                    }                    if (!ifaceMemberToClass.containsKey(ifaceMemberSym)                        && ifaceMemberSym.kind != Kinds.CLASS)                        ifaceMemberToClass.put(ifaceMemberSym, classMemberSym);                    classMembers.enter(classMemberSym);                }                switch (classSym.info()) {                case CompoundType(Type[] parts, Scope members):                    classSym.setInfo(Type.compoundType(tparamsSM.apply(parts),                                                       classMembers,                                                       classSym));                    break;                default:                    global.fail("unexpected type for class", ifaceSym.info());                }                Type cConstrType = classConstrSym.info();                classConstrSym.updateInfo(cConstrType.subst(new Symbol[]{ifaceSym},                                                            new Symbol[]{classSym}));                ifaceSym.flags |=                    (Modifiers.ABSTRACTCLASS | Modifiers.INTERFACE | Modifiers.STATIC);                classToInterface.put(classSym, ifaceSym);                super.traverse(impl);                if (ifaceTParams.length > 0)                    for (int i = 0; i < ifaceTParams.length; ++i)                        tparamsMap.remove(ifaceTParams[i]);                // Remove Java classes from interface base classes.                switch (ifaceSym.info()) {                case CompoundType(Type[] basetypes, Scope members):                    ArrayList newBT_L = new ArrayList(basetypes.length);                    for (int i = 0; i < basetypes.length; ++i)                        if (! basetypes[i].symbol().isJava())                            newBT_L.add(basetypes[i]);                    Type[] newBT;                    if (newBT_L.size() != basetypes.length)                        newBT = (Type[]) newBT_L.toArray(new Type[newBT_L.size()]);                    else                        newBT = basetypes;                    ifaceSym.updateInfo(Type.compoundType(newBT,                                                          newIFaceMembers,                                                          ifaceSym));                    break;                default:                    Debug.abort("unexpected type for class", ifaceSym.info());                }            } break;            default:                super.traverse(tree);            }        }