prefix = (JExpression)prefix.accept(this);
if (prefix==null) { prefix = new JThisExpression(); } else { prefix = (JExpression)prefix.accept(this); }
    public Object visitMethodCallExpression(JMethodCallExpression self,                                          JExpression prefix,                                          String ident,                                          JExpression[] args)     {	//Save method we were processing	String parentMethod = currentMethod;	blockStart("MethodCallExpression: " + self.getIdent(), self);        //Set currentMethod to this method, we are processing it!	currentMethod = self.getIdent();			if (isSIRExp(self)) {	    printMe("SIR Expression " + ident);	    //reset currentMethod on all returns	    currentMethod = parentMethod;	    return newSIRExp(self, args);	}	else if (ident.equals("regReceiver")) { 	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Exactly one arg to add() allowed");	    SIRStream st = ((SIRInitStatement)args[0].accept(this)).getTarget();	    currentMethod = parentMethod;	    //prefix can either be a field or a local var, extract type	    if (prefix instanceof JLocalVariableExpression)		return createRegReceiver(self, ((JLocalVariableExpression)prefix).getVariable().getType(),					 prefix, st);	    else if (prefix instanceof JFieldAccessExpression)		return createRegReceiver(self, ((JFieldAccessExpression)prefix).getType(),					 prefix, st);	    else		at.dms.util.Utils.fail(printLine(self) + 				       "regReceiver all must have a portal prefix");	    return null;	}        else if (ident.equals("setAnyLatency")) {            nextLatency = SIRLatency.BEST_EFFORT;            return null;        }        else if (ident.equals("setMaxLatency")) {            if (args.length > 1)                at.dms.util.Utils.fail(printLine(self) +                                       "Exactly one arg to setMaxLatency() allowed");            nextLatency = new SIRLatencyMax(args[0]);            return null;        }        else if (ident.equals("setLatency")) {            if (args.length > 2)                at.dms.util.Utils.fail(printLine(self) +                                       "Exactly two args to setLatency() allowed");            nextLatency = new SIRLatencyRange(args[0],                                              args[1]);            return null;        }	else if (ident.equals("add")) {            //Handle an add call in a pipeline	    //Parent must be a pipeline	    if (!((parentStream instanceof SIRPipeline) || parentStream instanceof SIRSplitJoin)) 		at.dms.util.Utils.fail(printLine(self) + 				       "Add not called on Pipeline or SplitJoin");	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Exactly one arg to add() allowed");	    //Visit the argument (Exactly one))	    Object SIROp = args[0].accept(this);	    	    	    //reset currentMethod on all returns	    currentMethod = parentMethod;	    //create the init statement 	    return createInitStatement(SIROp, ident);	    	} else if (ident.equals("setDelay")) {	    if (!(parentStream instanceof SIRFeedbackLoop))		at.dms.util.Utils.fail(printLine(self) + 				       "SetDelay called on Non-FeedbackLoop");	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Too many args to setDelay");	    JExpression delay  = (JExpression)args[0].accept(this);	    ((SIRFeedbackLoop)parentStream).setDelay(delay);	    //reset currentMethod on all returns	    currentMethod = parentMethod;	    //we want to ignore remove this method from the block	    return null;	}	else if (ident.equals("setBody")) {	    if (!(parentStream instanceof SIRFeedbackLoop)) 		at.dms.util.Utils.fail(printLine(self) + 				       "setBody called on non-FeedbackLoop");	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Exactly one arg to setBody() allowed");	    //Visited the argument	    Object SIROp = args[0].accept(this);	    //reset currentMethod on all returns	    currentMethod = parentMethod;	    //create the init statement to return	    return createInitStatement(SIROp, ident);	}	else if (ident.equals("setLoop")) {	    if (!(parentStream instanceof SIRFeedbackLoop)) 		at.dms.util.Utils.fail(printLine(self) + 				       "setLoop called on non-FeedbackLoop");	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Exactly one arg to setLoop() allowed");	    //Visited the argument	    Object SIROp = args[0].accept(this);	     //reset currentMethod on all returns	    currentMethod = parentMethod;	    //create the init statement to return	    return createInitStatement(SIROp, ident);	}       	else if (ident.equals("setSplitter")) {	    //we build the splitter here and set the global splitType	    //then we set the splitter in the postVisit of the stream	    buildSplitter(args[0]);	    currentMethod = parentMethod;	    return null;	}	else if (ident.equals("setJoiner")) {	    //we build the joiner here and set the global joinType	    //then we set the joiner in the postVisit of the stream	    buildJoiner(args[0]);	    currentMethod = parentMethod;	    //we want to ignore remove this method from the block	     return null;	}        else if (ident.equals("setIOTypes")) {            // Phased filter syntax for setting I/O types.  This has            // two arguments, which are null or Class objects.            args[0] = (JExpression)args[0].accept(this);            args[1] = (JExpression)args[1].accept(this);            if (parentStream instanceof SIRFilter)            {                SIRFilter filter = (SIRFilter)parentStream;		System.out.println(args[0]);		                if (args[0] instanceof JClassExpression) 		    filter.setInputType(((JClassExpression)args[0]).getClassType());                else if (args[0] instanceof JStringLiteral)                    filter.setInputType(getType(((JStringLiteral)args[0]).stringValue()));		else 		    Utils.fail(printLine(self) + "Malformed input type on I/O declaration");                if (args[1] instanceof JClassExpression)                     filter.setOutputType(((JClassExpression)args[1]).getClassType());		else if (args[1] instanceof JStringLiteral)                    filter.setOutputType(getType(((JStringLiteral)args[1]).stringValue()));		else 		    Utils.fail(printLine(self) + "Malformed output type on I/O declaration");            }            else if (parentStream instanceof SIRPhasedFilter)            {                SIRPhasedFilter filter = (SIRPhasedFilter)parentStream;                if (args[0] instanceof JClassExpression)                    filter.setInputType(((JClassExpression)args[0]).getClassType());                else if (args[0] instanceof JStringLiteral)                    filter.setInputType(getType(((JStringLiteral)args[0]).stringValue()));		else 		    Utils.fail(printLine(self) + "Malformed input type on I/O declaration");                if (args[1] instanceof JClassExpression)                    filter.setOutputType(((JClassExpression)args[1]).getClassType());                else if (args[1] instanceof JStringLiteral)                    filter.setOutputType(getType(((JStringLiteral)args[1]).stringValue()));		else 		    Utils.fail(printLine(self) + "Malformed output type on I/O declaration");            }            else                at.dms.util.Utils.fail(printLine(self) +                                       "setIOTypes() outside a filter");            return null;        }        else if (ident.equals("phase")) {            // This is special.  There should be one parameter, which            // is an anonymous stream creator; we need to get information            // out of this.            if (!(parentStream instanceof SIRPhasedFilter))                at.dms.util.Utils.fail(printLine(self) +                                       "Phase creation outside a phased filter");	    if (args.length > 1)		at.dms.util.Utils.fail(printLine(self) + 				       "Too many args to phase");            JExpression expr = args[0];            if (expr instanceof JUnaryPromote)                expr = ((JUnaryPromote)expr).getExpr();            // This could go inside a try...catch (ClassCastException) block.            // This appears to be the right type.  cf. JLS 15.9            JUnqualifiedAnonymousCreation uac =                (JUnqualifiedAnonymousCreation)(expr);            // uac should have three parameters; these are the peek, pop,            // and push rates, respectively.            JExpression[] pparams = uac.getParams();            if (pparams.length != 3)                at.dms.util.Utils.fail(printLine(self) +                                       "WorkFunction constructor needs exactly 3 params");            JExpression peek = pparams[0];            JExpression pop = pparams[1];            JExpression push = pparams[2];                        // Also, we need to look inside the class body to find the            // function being called:            JClassDeclaration decl = uac.getDecl();            JMethodDeclaration[] methods = decl.getMethods();            if (methods.length != 1)                at.dms.util.Utils.fail(printLine(self) +                                       "WorkFunction body can only have one function");            if (!(methods[0].getName().equals("work")))                at.dms.util.Utils.fail(printLine(self) +                                       "WorkFunction must contain work function");            // pass on validating other attributes of work()            JBlock body = methods[0].getBody();            if (body.size() != 1)                at.dms.util.Utils.fail(printLine(self) +                                       "WorkFunction work function must have exactly one statement");            JExpressionStatement stmt =                (JExpressionStatement)body.getStatement(0);            JMethodCallExpression fc =                (JMethodCallExpression)stmt.getExpression();            // At this point, we've won; we kind of want to search ourself            // to find the right function to turn into a phase, but we            // can do that later.            return new SIRPhaseInvocation(self.getTokenReference(),                                          fc, peek, pop, push, null);        }	//There are two cases for portal calls	//Message send to a portal using a local var to store the portal	//I think that this is the only case when prefix will not be null??? Keep the check any way	else if (prefix instanceof JLocalVariableExpression &&		 ((JLocalVariableExpression)prefix).getVariable().getType().toString().endsWith("Portal")) {	    //check if this is a regSender, if so ignore it	    if (ident.equals("regSender"))		return null;	    return createMessageStatement(self, ((JLocalVariableExpression)prefix).getVariable().getType(), 					  prefix, args);	}	//message send to portal using field as portal	else if (prefix instanceof JFieldAccessExpression &&		 ((JFieldAccessExpression)prefix).getType().toString().endsWith("Portal")) {	    if (ident.equals("regSender"))		return null;	    return createMessageStatement(self, ((JFieldAccessExpression)prefix).getType(), prefix, args);	}	          	else {             //Not an SIR call	    prefix = (JExpression)prefix.accept(this);	    for (int i = 0; i < args.length; i++)		args[i] = (JExpression) args[i].accept(this);	    //reset currentMethod	    currentMethod = parentMethod;	    self.setArgs(args);	    self.setPrefix(prefix);	    return self;	}    }