ifaceMemberSym.flags &= ~Modifiers.FINAL;
    protected Symbol getClassSymbol(Symbol ifaceSym) {        if (ifaceSym.isPrimaryConstructor())            return getClassSymbol(ifaceSym.constructorClass())                .primaryConstructor();        if (!needInterface(ifaceSym))            return ifaceSym;        Symbol classSym = (Symbol)ifaceToClass.get(ifaceSym);        if (classSym == null) {            classSym = ifaceSym.cloneSymbol(ifaceSym.owner());            classSym.name = className(ifaceSym.name);            classSym.flags &= ~Modifiers.INTERFACE;            // Remove non-primary constructors from interface            if (ifaceSym.allConstructors().isOverloaded()) {                Symbol primary = ifaceSym.primaryConstructor();                Symbol[] altsyms = { primary };                Type[] alttypes = { primary.nextType() };                Type allType = Type.OverloadedType(altsyms, alttypes);                ifaceSym.allConstructors().updateInfo(allType);            }            Scope ifaceOwnerMembers = ifaceSym.owner().members();            ifaceOwnerMembers.enter(classSym);            Type.SubstThisMap thisTypeMap =                new Type.SubstThisMap(ifaceSym, classSym);            // Create class substitution map.            SymbolSubstTypeMap classSubst = newClassSubst(classSym);            Map classMemberMap = newClassMemberMap(classSym);            Symbol[] allClassConstrs=                classSym.allConstructors().alternativeSymbols();            Symbol[] allIFaceConstrs=                ifaceSym.allConstructors().alternativeSymbols();            for (int i = 0; i < allClassConstrs.length; ++i) {                Symbol iConstr = allIFaceConstrs[i];                Symbol cConstr = allClassConstrs[i];                classSubst.insertSymbol(iConstr.typeParams(),                                        cConstr.typeParams());                classSubst.insertSymbol(iConstr.valueParams(),                                        cConstr.valueParams());                classMemberMap.put(iConstr, cConstr);            }            // Remove type of this            if (classSym.thisSym() != classSym)                classSym.setTypeOfThis(Type.NoType);            // Clone all members, entering them in the class scope.            Scope classMembers = new Scope();            Scope.SymbolIterator ifaceMembersIt =                new Scope.UnloadIterator(ifaceSym.members().iterator());            while (ifaceMembersIt.hasNext()) {                Symbol ifaceMemberSym = ifaceMembersIt.next();                if (ifaceMemberSym.isType()                    || ifaceMemberSym.isDeferred()                    || ifaceMemberSym.isPrimaryConstructor())                    continue;                Symbol classMemberSym;                if (memberGoesInInterface(ifaceMemberSym)) {                    if (ifaceMemberSym.isPrivate()) {                        ifaceMemberSym.name = uniqueName(ifaceMemberSym);                        ifaceMemberSym.flags ^= Modifiers.PRIVATE;                    } else if (ifaceMemberSym.isProtected())                        ifaceMemberSym.flags ^= Modifiers.PROTECTED;                    classMemberSym = ifaceMemberSym.cloneSymbol(classSym);                    classMemberSym.setInfo(                        thisTypeMap.applyParams(                            classSubst.applyParams(                                classMemberSym.info().cloneType(                                    ifaceMemberSym, classMemberSym))));                    ifaceMemberSym.flags |= Modifiers.DEFERRED;                } else {                    // Member doesn't go in interface, we just make it                    // owned by the class.                    classMemberSym = ifaceMemberSym;                    classMemberSym.setOwner(classSym);                    classMemberSym.updateInfo(                        thisTypeMap.apply(                            classSubst.apply(                                classMemberSym.info())));                }                classMemberMap.put(ifaceMemberSym, classMemberSym);                classMembers.enterOrOverload(classMemberSym);                if (classMemberSym.isClass())                    classMembers.enterOrOverload(classMemberSym.primaryConstructor());            }            // Give correct type to the class symbol by using class            // symbols for its parents, and by adding the interface            // among them.            Type[] oldClassParents = classSym.parents();            int oldParentsCount = oldClassParents.length;            Type[] newClassParents = new Type[oldParentsCount + 1];            for (int i = 0; i < oldParentsCount; ++i) {                switch (oldClassParents[i]) {                case TypeRef(Type pre, Symbol sym, Type[] args):                    Type newTp = Type.typeRef(pre, getClassSymbol(sym), args);                    newClassParents[i] = classSubst.apply(newTp);                    break;                default:                    throw Debug.abort("unexpected type for parent", oldClassParents[i]);                }            }            newClassParents[oldParentsCount] = classSubst.apply(ifaceSym.type());            // TODO setInfo cannot be used here because the type then            // goes through transformInfo. Maybe setInfo should behave            // like updateInfo.            classSym.updateInfo(Type.compoundType(newClassParents,                                                  classMembers,                                                  classSym));            ifaceToClass.put(ifaceSym, classSym);            classToIFace.put(classSym, ifaceSym);        }        return classSym;    }