tpe.type.typeArgs(), Symbol.type(tpe.type.typeParams()))) ? tpe.type.typeParams() : Symbol.EMPTY_ARRAY;
tpe.type.typeArgs(), Symbol.type(tpe.type.unalias().symbol().typeParams()))) ? tpe.type.unalias().symbol().typeParams() : Symbol.EMPTY_ARRAY;
    public Tree transform(Tree tree) {	Symbol sym = tree.symbol();	switch (tree) {	case ClassDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ):	    validateVariance(sym, sym.info(), CoVariance);	    validateVariance(sym, sym.typeOfThis(), CoVariance);	    return super.transform(		copy.ClassDef(tree, tree.symbol(), tparams, vparams, tpe, addCaseMethods(templ, tree.symbol())));	case DefDef(_, _, _, _, _, _):	    validateVariance(sym, sym.type(), CoVariance);	    return super.transform(tree);	case ValDef(_, _, _, _):	    validateVariance(		sym, sym.type(),		((sym.flags & MUTABLE) != 0) ? NoVariance : CoVariance);	    return super.transform(tree);	case TypeDef(_, _, _, _):	    if (sym.kind == ALIAS) {		validateVariance(sym, sym.info(), NoVariance);	    } else {		validateVariance(sym, sym.info(), CoVariance);		validateVariance(sym, sym.loBound(), ContraVariance);	    }	    return super.transform(tree);	    	case Template(Tree[] bases, Tree[] body):	    Tree[] bases1 = transform(bases);	    Tree[] body1 = transformStats(body);	    if (sym.kind == VAL) {		Symbol owner = tree.symbol().owner();		validateBaseTypes(owner);		checkAllOverrides(tree.pos, owner);	    }	    return copy.Template(tree, bases1, body1);	case Block(Tree[] stats):	    Tree[] stats1 = transformStats(stats);	    return copy.Block(tree, stats1);	case This(_):	    return tree;	case PackageDef(Tree pkg, Template packaged):	    return copy.PackageDef(tree, pkg, super.transform(packaged));	case TypeApply(Tree fn, Tree[] args):	    switch (fn.type) {	    case PolyType(Symbol[] tparams, Type restp):		checkBounds(tree.pos, tparams, Tree.typeOf(args));	    }	    return super.transform(tree);	case Apply(Tree fn, Tree[] args):	    Symbol fsym = TreeInfo.methSymbol(fn);	    if (fsym != null && fsym.isMethod() && !fsym.isConstructor() &&		(fsym.flags & CASE) != 0) {		// convert case methods to new's		Symbol constr = fsym.type().resultType().symbol().constructor();		tree = gen.New(toConstructor(tree, constr));	    }	    return super.transform(tree);	case AppliedType(Tree tpe, Tree[] args):	    //todo: this needs to be refined.	    Symbol[] tparams = 		(Type.isSameAs(		    tpe.type.typeArgs(), Symbol.type(tpe.type.typeParams())))		? tpe.type.typeParams() : Symbol.EMPTY_ARRAY;	    checkBounds(tree.pos, tparams, Tree.typeOf(args));	    return elimTypeNode(super.transform(tree));	case CompoundType(_, _):	    Symbol clazz = tree.type.symbol();	    validateBaseTypes(clazz);	    checkAllOverrides(tree.pos, clazz);	    return elimTypeNode(super.transform(tree));	case Ident(Name name):	    if( TreeInfo.isWildcardPattern( tree ) ) 		return elimTypeNode(tree);	    	    //System.out.println("name: "+name);	    Scope.Entry e = scopes[level].lookupEntry(name);	    //System.out.println("sym: "+sym);	    if (sym.isLocal() && sym == e.sym) {		int i = level;		while (scopes[i] != e.owner) i--;		int symindex = ((Integer) symIndex.get(tree.symbol())).intValue();		if (maxindex[i] < symindex) {		    refpos[i] = tree.pos;		    refsym[i] = e.sym;		    maxindex[i] = symindex;		}	    }	    return elimTypeNode(tree);	default:	    return elimTypeNode(super.transform(tree));	}	    }