TreeCloner treeCloner = new MyTreeCloner( global, symbolCloner.clones, typeCloner, owner);
TreeCloner treeCloner = new TreeCloner( global, symbolCloner.clones, typeCloner);
    protected Template expandMixins(Template tree, final Symbol owner) {        Type templType = owner.info();        List/*<Tree>*/ newBody = new ArrayList();	Scope newMembers = new Scope();        Symbol newTemplSymbol = tree.symbol().cloneSymbol();        // Start by copying the statement sequence.        Tree[] body = tree.body;        for (int i = 0; i < body.length; ++i) {            Tree stat = body[i];            newBody.add(transform(stat));            if (stat.definesSymbol()) {		Symbol sym = stat.symbol();		newMembers.enterOrOverload(sym);            }        }        Type[] baseTypes = owner.parents();        global.log("baseTypes for " + Debug.show(owner)                   + " = <" + ArrayApply.toString(baseTypes) + ">");        // Then go over the mixins and mix them in.        for (int bcIndex = tree.parents.length - 1; bcIndex > 0; --bcIndex) {            SymbolCloner symbolCloner =                new SymbolCloner(global.freshNameCreator);            SymbolSubstTypeMap typeCloner = new SymbolSubstTypeMap();            Tree bc = tree.parents[bcIndex];            final Symbol bcSym = baseTypes[bcIndex].symbol();            symbolCloner.owners.put(bcSym, owner);            symbolCloner.owners.put(bcSym.constructor(), owner);            if ((bcSym.flags & Modifiers.INTERFACE) != 0)                continue;            assert classDefs.containsKey(bcSym) : bcSym;            ClassDef bcDef = (ClassDef)classDefs.get(bcSym);            // Create substitution for mixin's type parameters.            Object[] ts = typeSubst(baseTypes[bcIndex]);            assert ts.length == 2;            final Symbol[] tpFormals = (Symbol[])ts[0];            final Type[] tpActuals = (Type[])ts[1];            assert tpFormals.length == tpActuals.length;            Type.Map typeMap = new Type.Map() {                    public Type apply(Type t) {                        Type t1 = t.asSeenFrom(owner.thisType(), bcSym);                        Type t2 = t1.subst(tpFormals, tpActuals);                        return t2;                    }                };            typeCloner.insertType(tpFormals, tpActuals);            // Create private fields for mixin's value parameters.            Tree[][] actuals = getArgsSection(bc);            assert bcDef.vparams.length == actuals.length;            for (int s = 0; s < bcDef.vparams.length; ++s) {                ValDef[] sectionF = bcDef.vparams[s];                Tree[] sectionA = actuals[s];                assert sectionF.length == sectionA.length;                for (int p = 0; p < sectionF.length; ++p) {                    // We do not need to copy the actual parameters,                    // since they are removed from their original                    // location anyway.                    ValDef formal = sectionF[p];                    Tree actual = sectionA[p];                    Symbol memberSymbol =                        symbolCloner.cloneSymbol(formal.symbol(), true);                    Type memberType = typeMap.apply(formal.tpe.type());                    memberSymbol.updateInfo(memberType);                    Tree memberDef = gen.ValDef(memberSymbol, actual);                    newBody.add(memberDef);                    typeCloner.insertSymbol(formal.symbol(), memberSymbol);                }            }            Template mixin = getMixinExpandedTemplate(bcDef.impl, bcSym);            Type bcType = mixin.type();            Tree[] mixinBody = mixin.body;            Map newNames = new HashMap();            // Pass 1: compute members to rename.            for (int m = 0; m < mixinBody.length; ++m) {                Tree member = mixinBody[m];                if (!member.definesSymbol()) continue;                Symbol symbol = member.symbol();                Name newName = (Name)newNames.get(symbol.name);                boolean shadowed = newName == null &&                    newMembers.lookup(symbol.name) != Symbol.NONE;                if (shadowed && symbol.isDeferred()) continue;                Symbol clone = symbolCloner.cloneSymbol(symbol, shadowed);                if (newName != null)                    clone.name = newName;                else                    newNames.put(symbol.name, clone.name);                typeCloner.insertSymbol(symbol, clone);                newMembers.enterOrOverload(clone);            }            // Pass 2: copy members            TreeSymbolCloner treeSymbolCloner =                new TreeSymbolCloner(symbolCloner);            TreeCloner treeCloner = new MyTreeCloner(                global, symbolCloner.clones, typeCloner, owner);            for (int m = 0; m < mixinBody.length; ++m) {                Tree member = mixinBody[m];                if (symbolCloner.clones.containsKey(member.symbol())) {                    treeSymbolCloner.traverse(member);                    newBody.add(treeCloner.transform(member));                }            }        }	// Modify mixin base classes to refer to interfaces instead of	// real classes.	Type[] newBaseTypes = new Type[baseTypes.length];	Tree[] newBaseClasses = new Tree[tree.parents.length];        newBaseTypes[0] = baseTypes[0];        newBaseClasses[0] = tree.parents[0];	for (int i = 1; i < baseTypes.length; ++i) {	    switch (baseTypes[i]) {	    case TypeRef(Type pre, Symbol sym, Type[] args): {		if (!Modifiers.Helper.isInterface(sym.flags))                    sym = addInterfaces.getInterfaceSymbol(sym);                newBaseClasses[i] =                    gen.mkParentConstr(tree.pos, new Type.TypeRef(pre, sym, args));		newBaseTypes[i] = new Type.TypeRef(pre, sym, args);	    } break;	    default:		throw global.fail("invalid base class type", baseTypes[i]);	    }	}        Tree[] fixedBody = (Tree[])newBody.toArray(new Tree[newBody.size()]);        Template newTree = make.Template(tree.pos, newBaseClasses, fixedBody);        newTree.setSymbol(newTemplSymbol);	newTree.setType(Type.compoundType(newBaseTypes, newMembers, owner));        return newTree;    }