if (node.contents instanceof SIRTwoStageFilter) {    }
    private boolean canFire(FlatNode node, HashMap executionCounts, 			    SimulationCounter counters)     {	if (node == null)	    return false;	if (node.contents instanceof SIRFilter) {	    //check if this node has fired the number of times given by	    //the schedule	    Integer count = (Integer)executionCounts.get(node);	    //if a node is not executed at all in a schedule it will not have an	    //entry	    if (count == null)		return false;	    if (count.intValue() == 0) {		return false;	    }	    if (counters.getBufferCount(node) >= itemsNeededToFire(node, counters)) {		return true;	    }	    else		return false;	}	else if (node.contents instanceof SIRJoiner) {	    //first of all, a joiner can only fire it is the most downstream	    //joiner in a joiner group	    if (!Layout.joiners.contains(node))		return false;	    //determine if the joiner can receive and buffer data	    //this does not count as an execution of the joiner	    //only sending data counts as an execution, that is why we check that 	    //next	    if (counters.getBufferCount(node) > 0) 		return true;	    	    //check if this node has fired the number of times given by	    //the schedule	    Integer count = (Integer)executionCounts.get(node);	    //if a node is not executed at all in a schedule it will not have an	    //entry	    if (count == null)		return false;	    if (count.intValue() == 0) {		return false;	    }	    	    //determine if the joiner can send data downstream from a buffer	    if (counters.getJoinerBufferCount(node, counters.	    				      getJoinerBuffer(node)) > 0)		return true;	    else		return false;	}	else 	    return false;    }