Program: 74307
Project: 74307
Buggy source:
/** 
 * Create subgraphs for all tasks, interconnect them with mode switches and other tasks.
 * @param refinement
 * @param modePeriod
 * @throws TDLModeSchedulerException
 * @throws IllegalActionException
 */
private void _getTasks(State mode,Refinement refinement,Time modePeriod) throws IllegalActionException {
  List<TDLTask> tasks=(List<TDLTask>)refinement.entityList();
  for (  TDLTask taskActor : tasks) {
    LetTask task=_analyzeSlotSelection(taskActor,modePeriod);
    List<ModalPort> sensors=taskActor.getSensorsReadFrom(refinement.inputPortList(),_module.inputPortList());
    Node modeSwitchEnd=null, modeSwitchStart=null;
    if (_tmpModeSwitchStarts == null || _tmpModeSwitchStarts.size() == 0) {
      Time time=new Time(_module.getDirector(),0);
      modeSwitchStart=modeSwitchEnd=_createNode(time,TDLAction.AFTERMODESWITCH,mode);
      _tmpModeSwitchStarts.put(time,modeSwitchStart);
      _tmpModeSwitchEnds.put(time,modeSwitchStart);
    }
 else {
      modeSwitchStart=_tmpModeSwitchStarts.get(new Time(_module.getDirector(),0.0));
      if (modeSwitchStart == null)       modeSwitchStart=(Node)_tmpModeSwitchStarts.get(modePeriod);
    }
    if (_tmpModeSwitchEnds != null && _tmpModeSwitchEnds.size() != 0) {
      modeSwitchEnd=(Node)_tmpModeSwitchEnds.get(new Time(_module.getDirector(),0.0));
      if (modeSwitchEnd == null)       modeSwitchEnd=(Node)_tmpModeSwitchEnds.get(modePeriod);
    }
    List<Node> outputPortNodes=null;
    Node invocationEndNode=modeSwitchEnd;
    for (long i=task.getOffset(); i < modePeriod.getLongValue(); i+=task.getInvocationPeriod()) {
      Time invocationTime=new Time(_module.getDirector(),i);
      List<IOPort> notConnectedToSensors=new ArrayList();
      notConnectedToSensors.addAll(taskActor.inputPortList());
      List<Node> inputPortNodes=new ArrayList();
      for (      ModalPort sensor : sensors) {
        Node sensorNode=null, inputPortNode=null;
        if ((_tmpReadSensors.size() == 0) || _tmpReadSensors.get(invocationTime) == null || !((List)_tmpReadSensors.get(invocationTime)).contains(sensor)) {
          sensorNode=_createNode(invocationTime,TDLAction.READSENSOR,sensor,invocationEndNode);
        }
 else {
          sensorNode=getNode(invocationTime,sensor);
          boolean sensorWasReadBeforeModeSwitch=false;
          List<Edge> edges=(List<Edge>)_graph.outputEdges(sensorNode);
          if (edges.size() > 0) {
            Node targetNode=edges.get(0).sink();
            while (((TDLAction)targetNode.getWeight()).actionType == TDLAction.READSENSOR) {
              edges=(List<Edge>)_graph.outputEdges(targetNode);
              targetNode=edges.get(0).sink();
            }
            if (((TDLAction)targetNode.getWeight()).actionType == TDLAction.MODESWITCH) {
              sensorWasReadBeforeModeSwitch=true;
            }
          }
          if (sensorWasReadBeforeModeSwitch)           sensorNode=modeSwitchEnd;
        }
        List<IOPort> inputPorts=taskActor.inputPortList();
        for (        IOPort inputPort : inputPorts) {
          if (inputPort.isDeeplyConnected(sensor)) {
            notConnectedToSensors.remove(inputPort);
            inputPortNode=_createNode(invocationTime,TDLAction.READINPUT,inputPort,sensorNode);
            inputPortNodes.add(inputPortNode);
            _registerTaskInputPortReading(invocationTime,(IOPort)inputPort);
            _connectToOtherTasksOutputPorts(inputPort);
          }
        }
      }
      Node taskExecutionNode=_createNode(invocationTime,TDLAction.EXECUTETASK,taskActor);
      for (      IOPort notConnectedToSensor : notConnectedToSensors) {
        Node inputPortNode=_createNode(invocationTime,TDLAction.READINPUT,notConnectedToSensor,invocationEndNode);
        inputPortNodes.add(inputPortNode);
      }
      if (inputPortNodes.size() == 0) {
        Edge edge=new Edge(invocationEndNode,taskExecutionNode);
        _graph.addEdge(edge);
      }
      for (      Node inputPortNode : inputPortNodes) {
        Edge edge=new Edge(inputPortNode,taskExecutionNode);
        _graph.addEdge(edge);
      }
      outputPortNodes=new ArrayList();
      Node outputPortNode=null;
      List<IOPort> outputPorts=taskActor.outputPortList();
      for (      IOPort outputPort : outputPorts) {
        Time writePortTime=new Time(_module.getDirector(),i + task.getLet());
        outputPortNode=_createNode(writePortTime,TDLAction.WRITEOUTPUT,outputPort,taskExecutionNode);
        outputPortNodes.add(outputPortNode);
        _connectToIntermediateModeSwitch(outputPortNode,new Time(_module.getDirector(),i),new Time(_module.getDirector(),task.getInvocationPeriod()));
      }
      if (outputPortNodes.size() == 0) {
        invocationEndNode=taskExecutionNode;
      }
 else       if (outputPortNodes.size() == 1) {
        invocationEndNode=outputPortNodes.get(0);
      }
 else       if (outputPortNodes.size() > 1) {
        invocationEndNode=getNode(new Time(_module.getDirector(),0),null);
        if (invocationEndNode == null)         invocationEndNode=_createNode(new Time(_module.getDirector(),i),TDLAction.AFTERTASKOUTPUTS,null);
      }
    }
    for (    Node outputPortNode : outputPortNodes) {
      Edge edge=new Edge(outputPortNode,modeSwitchStart,modePeriod.subtract(((TDLAction)outputPortNode.getWeight()).time));
      _graph.addEdge(edge);
    }
  }
  _addConnectionsBetweenTaskPorts();
}

Fixed version (ground truth):
/** 
 * Create subgraphs for all tasks, interconnect them with mode switches and other tasks.
 * @param refinement
 * @param modePeriod
 * @throws TDLModeSchedulerException
 * @throws IllegalActionException
 */
private void _getTasks(State mode,Refinement refinement,Time modePeriod) throws IllegalActionException {
  List<TDLTask> tasks=(List<TDLTask>)refinement.entityList();
  Time timeZero=new Time(_module.getDirector(),0.0);
  for (  TDLTask taskActor : tasks) {
    LetTask task=_analyzeSlotSelection(taskActor,modePeriod);
    List<ModalPort> sensors=taskActor.getSensorsReadFrom(refinement.inputPortList(),_module.inputPortList());
    Node modeSwitchEnd=null, modeSwitchStart=null;
    if (_tmpModeSwitchStarts == null || _tmpModeSwitchStarts.size() == 0) {
      modeSwitchStart=modeSwitchEnd=_createNode(timeZero,TDLAction.AFTERMODESWITCH,mode);
      _tmpModeSwitchStarts.put(timeZero,modeSwitchStart);
      _tmpModeSwitchEnds.put(timeZero,modeSwitchStart);
    }
 else {
      modeSwitchStart=_tmpModeSwitchStarts.get(timeZero);
      if (modeSwitchStart == null)       modeSwitchStart=(Node)_tmpModeSwitchStarts.get(modePeriod);
    }
    if (_tmpModeSwitchEnds != null && _tmpModeSwitchEnds.size() != 0) {
      modeSwitchEnd=(Node)_tmpModeSwitchEnds.get(timeZero);
      if (modeSwitchEnd == null)       modeSwitchEnd=(Node)_tmpModeSwitchEnds.get(modePeriod);
    }
    List<Node> outputPortNodes=null;
    Node invocationEndNode=modeSwitchEnd;
    for (long i=task.getOffset(); i < modePeriod.getLongValue(); i+=task.getInvocationPeriod()) {
      Time invocationTime=new Time(_module.getDirector(),i);
      List<IOPort> notConnectedToSensors=new ArrayList();
      notConnectedToSensors.addAll(taskActor.inputPortList());
      List<Node> inputPortNodes=new ArrayList();
      for (      ModalPort sensor : sensors) {
        Node sensorNode=null, inputPortNode=null;
        if ((_tmpReadSensors.size() == 0) || _tmpReadSensors.get(invocationTime) == null || !((List)_tmpReadSensors.get(invocationTime)).contains(sensor)) {
          sensorNode=_createNode(invocationTime,TDLAction.READSENSOR,sensor,invocationEndNode);
        }
 else {
          sensorNode=getNode(invocationTime,sensor);
          boolean sensorWasReadBeforeModeSwitch=false;
          List<Edge> edges=(List<Edge>)_graph.outputEdges(sensorNode);
          if (edges.size() > 0) {
            Node targetNode=edges.get(0).sink();
            while (((TDLAction)targetNode.getWeight()).actionType == TDLAction.READSENSOR) {
              edges=(List<Edge>)_graph.outputEdges(targetNode);
              targetNode=edges.get(0).sink();
            }
            if (((TDLAction)targetNode.getWeight()).actionType == TDLAction.MODESWITCH) {
              sensorWasReadBeforeModeSwitch=true;
            }
          }
          if (sensorWasReadBeforeModeSwitch)           sensorNode=modeSwitchEnd;
        }
        List<IOPort> inputPorts=taskActor.inputPortList();
        for (        IOPort inputPort : inputPorts) {
          if (inputPort.isDeeplyConnected(sensor)) {
            notConnectedToSensors.remove(inputPort);
            inputPortNode=_createNode(invocationTime,TDLAction.READINPUT,inputPort,sensorNode);
            inputPortNodes.add(inputPortNode);
            _registerTaskInputPortReading(invocationTime,(IOPort)inputPort);
            _connectToOtherTasksOutputPorts(inputPort);
          }
 else {
          }
        }
      }
      Node taskExecutionNode=_createNode(invocationTime,TDLAction.EXECUTETASK,taskActor);
      for (      IOPort notConnectedToSensor : notConnectedToSensors) {
        Node inputPortNode=_createNode(invocationTime,TDLAction.READINPUT,notConnectedToSensor,invocationEndNode);
        inputPortNodes.add(inputPortNode);
      }
      if (inputPortNodes.size() == 0) {
        Edge edge=new Edge(invocationEndNode,taskExecutionNode);
        _graph.addEdge(edge);
      }
      for (      Node inputPortNode : inputPortNodes) {
        Edge edge=new Edge(inputPortNode,taskExecutionNode);
        _graph.addEdge(edge);
      }
      outputPortNodes=new ArrayList();
      Node outputPortNode=null;
      List<IOPort> outputPorts=taskActor.outputPortList();
      for (      IOPort outputPort : outputPorts) {
        Time writePortTime=new Time(_module.getDirector(),i + task.getLet());
        Time nextInvocationTime=new Time(_module.getDirector(),i + task.getLet() + task.getOffset());
        if (nextInvocationTime.equals(modePeriod))         nextInvocationTime=timeZero;
        outputPortNode=_createNode(writePortTime,TDLAction.WRITEOUTPUT,outputPort,taskExecutionNode);
        outputPortNodes.add(outputPortNode);
        _connectToIntermediateModeSwitch(outputPortNode,new Time(_module.getDirector(),i),new Time(_module.getDirector(),task.getInvocationPeriod()));
      }
      if (outputPortNodes.size() == 0) {
        invocationEndNode=taskExecutionNode;
      }
 else       if (outputPortNodes.size() == 1) {
        invocationEndNode=outputPortNodes.get(0);
      }
 else       if (outputPortNodes.size() > 1) {
        invocationEndNode=getNode(new Time(_module.getDirector(),0),null);
        if (invocationEndNode == null)         invocationEndNode=_createNode(new Time(_module.getDirector(),i),TDLAction.AFTERTASKOUTPUTS,null);
      }
    }
    for (    Node outputPortNode : outputPortNodes) {
      Edge edge=new Edge(outputPortNode,modeSwitchStart,modePeriod.subtract(((TDLAction)outputPortNode.getWeight()).time));
      _graph.addEdge(edge);
    }
  }
  _addConnectionsBetweenTaskPorts();
}