if (qual.type.isSameAs(state.currentClass.thisType().widen())) {
if ((state.currentClass.isModuleClass() && qual.type.isSameAs(state.currentClass.thisType().widen())) || (qual instanceof This && qual.symbol() == state.currentClass)){
    public Tree transform(Tree tree) {        switch (tree) {	case DefDef(int mods, Name name, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): {	    AbsTypeDef[] newTparams  = tail_transform(tparams,false);	    ValDef[][] newVparams = tail_transform(vparams,false);	    Tree newTpe   = tail_transform(tpe,false);	    /* Create a new symbol for the LabelDef */	    Symbol newLabel = new TermSymbol(tree.pos, name, tree.symbol(), Modifiers.LABEL);	    newLabel.setInfo(tree.symbol().type());	    /* Push information about the label on the state stack. */	    push_label(newLabel);	    state.inTailPosition = true;	    state.currentFunction = tree.symbol();	    /* Traverse the body of the function */	    Tree newRhs   = transform(rhs);	    /* Was a tail-call inserted? */	    if (state.needLabelDef) {		pop(); // Pop the label-state from the stack.		// The LabelDef needs identifiers as parameters.		Ident [] args = to_ident(newVparams[0]);		// Create a new LabelDef with the new body of the function as the rhs		Tree labelDef = new ExtLabelDef(newLabel,args,newRhs).setType(newRhs.type());		// Create a new function node with the LabelDef as the rhs.		return copy.DefDef(tree,tree.symbol(), newTparams,				   newVparams, newTpe, labelDef);	    } else { // No recursive tail-vall inserted.		pop(); // Pop the label-state from the stack.		// Don't insert the LabelDef.		return copy.DefDef(tree,tree.symbol(), newTparams,				   newVparams, newTpe, newRhs);	    }	}	case Apply(Tree fun, Tree[] args): {	    if (state.inTailPosition) {  // This is a tail-call		switch (fun) {		case Select(Tree qual, Name name): 		    if (state.currentFunction == fun.symbol()) { // Is is self-recursive?			// Make sure that function is from the same class as we are in.			if (qual.type.isSameAs(state.currentClass.thisType().widen())) {			    // We can only rewrite final functions in a safe way.			    // (Local lifted functions should be safe but they should			    //  have the final flag set.)			    Modifiers.Helper H = new Modifiers.Helper();			    if(H.isFinal(state.currentFunction.flags)) { // Is the function final?				Tree[] newArgs = tail_transform(args,false);				// Redirect the call to the LabelDef.				Tree newTarget = new ExtIdent(state.newLabel).setType(fun.type());				// Indicate that we have inserted a tail call.				state.needLabelDef = true;				return copy.Apply(tree,newTarget,newArgs);  			    }			}		    }		    break;		default:		    break;		}	    } 	    // Call not in tail-pos: recurse over the arguments.	    Tree[] newArgs = tail_transform(args,false);	    Tree newFun = tail_transform(fun,false);	    //  global.debugPrinter.print("OldApply fun "+newFun.symbol().name).println().end();	    return copy.Apply(tree, newFun, newArgs); 	}	case ClassDef(int mods, Name name, AbsTypeDef[] tparams, 		      ValDef[][] vparams, Tree tpe, Template impl): {	    return copy.ClassDef(tree, tree.symbol(),tparams,vparams,tpe,				 transform_class(impl,tree.symbol()));	}        case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound):	    return copy.AbsTypeDef(tree, tree.symbol(), 				   tail_transform(rhs,false),				   tail_transform(lobound,false));       case CaseDef(Tree pat, Tree guard, Tree body):            return copy.CaseDef(tree, 				tail_transform(pat,false),				tail_transform(guard,false),				transform(body));       case Template(Tree[] parents, Tree[] body):	   return copy.Template(tree, tree.symbol(), 				tail_transform(parents,false),				transform(body));	case Block(Tree[] stats): {	    int last = stats.length-1;	    // All statements except the last will not be tail-calls	    for (int i = 0; i < last; i++) {		Tree t = tail_transform(stats[i],false);		// We are a bit paranoid about creating garbage...		if (t != stats[i]) { // ... so we only copy the tree if it changes.		    Tree[] res = new Tree[stats.length];		    // copy all the preceding statements to the new array.		    System.arraycopy(stats, 0, res, 0, i);		    res[i++] = t;		    // Put all the following statements in the new array.		    for (; i < last; i++)			res[i] = tail_transform(stats[i],false);		    // The last statement might be in a tail position.		    res[last] = transform(stats[last]);		    return copy.Block(tree,res);		}	    } // No change in the tree after handling all but the last statement.	    if (last > 0) {		Tree t = transform(stats[last]);		if (t != stats[last]) {		    Tree[] res = new Tree[stats.length];		    System.arraycopy(stats, 0, res, 0, last);		    res[last] = t;		    return copy.Block(tree,res);		} 	    }	    // No change at all            return copy.Block(tree,stats);	}        case Sequence(Tree[] trees):             return copy.Sequence(tree, tail_transform(trees,false));        case Assign(Tree lhs, Tree rhs):            return copy.Assign(tree, 			       tail_transform(lhs,false),			       tail_transform(rhs,false));	case If(Tree cond, Tree thenp, Tree elsep): {            return copy.If(tree, tail_transform(cond,false),			   transform(thenp),			   transform(elsep));	}	case New(Template templ):	    // At the moment we assume that the call to the constructor can not be	    // a tailcall.            return copy.New(tree, tail_transform(templ,false));        case Typed(Tree expr, Tree tpe):            return copy.Typed(tree, 			      transform(expr),			      tail_transform(tpe,false));        case TypeApply(Tree fun, Tree[] args):            return copy.TypeApply(tree, 				  tail_transform(fun,false),				  tail_transform(args,false));        default:            return super.transform(tree);        }    }