Program: 74002
Project: 74002
Buggy source:
/** 
 * Return the actor to fire in this iteration, or null if no actor should be fired. In this base class, this method first checks whether the top event from the event queue is destined for an actuator. If it is, then we check if physical time has reached the timestamp of the actuation event. If it has, then we fire the actuator. If it has not, then we take the actuator event from the event queue and put it onto the _realTimeEventQueue, and call fireAt() of the executive director. We then check if a real-time event should be processed by looking at the top event of the _realTimeEventQueue. If there is on that should be fired, that actor is returned for firing. If not, we go on and considers two cases, depending whether there is an actor currently executing, as follows: <p> <b>Case 1</b>: If there is no actor currently executing, then this method checks the event queue and returns null if it is empty. If it is not empty, it checks the destination actor of the earliest event on the event queue, and if it has a non-zero execution time, then it pushes it onto the currently executing stack and returns null. Otherwise, if the execution time of the actor is zero, it sets the current model time to the time stamp of that earliest event and returns that actor. <p> <b>Case 2</b>: If there is an actor currently executing, then this method checks whether it has a remaining execution time of zero. If it does, then it returns the currently executing actor. If it does not, then it checks whether the earliest event on the event queue should preempt it (by invoking _preemptExecutingActor()), and if so, checks the destination actor of that event and removes the event from the event queue. If that destination actor has an execution time of zero, then it sets the current model time to the time stamp of that event, and returns that actor. Else if the destination actor has an execution time of bigger than zero, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null. If there is no event on the event queue or that event should not preempt the currently executing actor, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null.
 * @return The next actor to be fired, which can be null.
 * @exception IllegalActionException If event queue is not ready, oran event is missed, or time is set backwards, or if the enclosing director does not respect the fireAt call.
 * @see #_preemptExecutingActor()
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  Time physicalTime=_getPhysicalTime();
  Actor container=(Actor)getContainer();
  Director executiveDirector=container.getExecutiveDirector();
  if (!_currentlyExecutingStack.isEmpty()) {
    DoubleTimedEvent currentEventList=(DoubleTimedEvent)_currentlyExecutingStack.peek();
    Time remainingExecutionTime=currentEventList.remainingExecutionTime;
    Time finishTime=_physicalTimeExecutionStarted.add(remainingExecutionTime);
    int comparison=finishTime.compareTo(physicalTime);
    if (comparison < 0) {
      throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
    }
 else     if (comparison == 0) {
      setTag(currentEventList.timeStamp,currentEventList.microstep);
      _currentlyExecutingStack.pop();
      _physicalTimeExecutionStarted=physicalTime;
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName(getContainer()) + "String_Node_Str"+ physicalTime);
      }
      _setIcon(_getIdleIcon(),false);
      _clearHighlight(_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),false);
      _lastExecutingActor=null;
      executiveDirector.fireAtCurrentTime((Actor)container);
      return _getActorFromEventList((List<PtidesEvent>)currentEventList.contents);
    }
 else {
      Time nextEventOnStackFireTime=_currentlyExecutingStack.peek().remainingExecutionTime;
      Time expectedCompletionTime=nextEventOnStackFireTime.add(_physicalTimeExecutionStarted);
      Time fireAtTime=executiveDirector.fireAt(container,expectedCompletionTime);
      if (!fireAtTime.equals(expectedCompletionTime)) {
        throw new IllegalActionException(executiveDirector,"String_Node_Str" + expectedCompletionTime + "String_Node_Str"+ fireAtTime);
      }
      if (_eventQueue.isEmpty() || !_preemptExecutingActor()) {
        return null;
      }
    }
  }
  if (_eventQueue.isEmpty()) {
    _setIcon(_getIdleIcon(),false);
    return null;
  }
  PtidesEvent eventFromQueue=_getNextSafeEvent();
  if (eventFromQueue == null) {
    return null;
  }
  Time timeStampOfEventFromQueue=eventFromQueue.timeStamp();
  int microstepOfEventFromQueue=eventFromQueue.microstep();
  _trackLastTagConsumedByActor(eventFromQueue);
  List<PtidesEvent> eventsToProcess=_getAllSameTagEventsFromQueue(eventFromQueue);
  Actor actorToFire=_getNextActorToFireForTheseEvents(eventsToProcess);
  IOPort ioPort=eventFromQueue.ioPort();
  if (ioPort == null) {
    List<IOPort> inPortList=eventFromQueue.actor().inputPortList();
    ioPort=inPortList.get(0);
  }
  _lastSourcePort=ioPort;
  Time executionTime=new Time(this,_getExecutionTime(ioPort));
  if (executionTime.compareTo(_zero) == 0) {
    setTag(timeStampOfEventFromQueue,microstepOfEventFromQueue);
    executiveDirector.fireAtCurrentTime((Actor)container);
    return actorToFire;
  }
 else {
    Time expectedCompletionTime=physicalTime.add(executionTime);
    Time fireAtTime=executiveDirector.fireAt(container,expectedCompletionTime);
    if (!fireAtTime.equals(expectedCompletionTime)) {
      throw new IllegalActionException(actorToFire,executiveDirector,"String_Node_Str" + expectedCompletionTime + "String_Node_Str"+ fireAtTime);
    }
    if (!_currentlyExecutingStack.isEmpty()) {
      DoubleTimedEvent currentEventList=_currentlyExecutingStack.peek();
      Time elapsedTime=physicalTime.subtract(_physicalTimeExecutionStarted);
      currentEventList.remainingExecutionTime=currentEventList.remainingExecutionTime.subtract(elapsedTime);
      if (currentEventList.remainingExecutionTime.compareTo(_zero) < 0) {
        throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
      }
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName((NamedObj)container) + "String_Node_Str"+ physicalTime+ "String_Node_Str"+ currentEventList.remainingExecutionTime);
      }
    }
    _currentlyExecutingStack.push(new DoubleTimedEvent(timeStampOfEventFromQueue,microstepOfEventFromQueue,eventsToProcess,executionTime));
    _physicalTimeExecutionStarted=physicalTime;
    _setIcon(_getExecutingIcon(actorToFire),false);
    _lastExecutingActor=actorToFire;
    return null;
  }
}

Fixed version (ground truth):
/** 
 * Return the actor to fire in this iteration, or null if no actor should be fired. In this base class, this method first checks whether the top event from the event queue is destined for an actuator. If it is, then we check if physical time has reached the timestamp of the actuation event. If it has, then we fire the actuator. If it has not, then we take the actuator event from the event queue and put it onto the _realTimeEventQueue, and call fireAt() of the executive director. We then check if a real-time event should be processed by looking at the top event of the _realTimeEventQueue. If there is on that should be fired, that actor is returned for firing. If not, we go on and considers two cases, depending whether there is an actor currently executing, as follows: <p> <b>Case 1</b>: If there is no actor currently executing, then this method checks the event queue and returns null if it is empty. If it is not empty, it checks the destination actor of the earliest event on the event queue, and if it has a non-zero execution time, then it pushes it onto the currently executing stack and returns null. Otherwise, if the execution time of the actor is zero, it sets the current model time to the time stamp of that earliest event and returns that actor. <p> <b>Case 2</b>: If there is an actor currently executing, then this method checks whether it has a remaining execution time of zero. If it does, then it returns the currently executing actor. If it does not, then it checks whether the earliest event on the event queue should preempt it (by invoking _preemptExecutingActor()), and if so, checks the destination actor of that event and removes the event from the event queue. If that destination actor has an execution time of zero, then it sets the current model time to the time stamp of that event, and returns that actor. Else if the destination actor has an execution time of bigger than zero, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null. If there is no event on the event queue or that event should not preempt the currently executing actor, then it calls fireAt() on the enclosing director passing it the time it expects the currently executing actor to finish executing, and returns null.
 * @return The next actor to be fired, which can be null.
 * @exception IllegalActionException If event queue is not ready, oran event is missed, or time is set backwards, or if the enclosing director does not respect the fireAt call.
 * @see #_preemptExecutingActor()
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  Time physicalTime=_getPhysicalTime();
  Actor container=(Actor)getContainer();
  Director executiveDirector=container.getExecutiveDirector();
  if (!_currentlyExecutingStack.isEmpty()) {
    DoubleTimedEvent currentEventList=(DoubleTimedEvent)_currentlyExecutingStack.peek();
    Time remainingExecutionTime=currentEventList.remainingExecutionTime;
    Time finishTime=_physicalTimeExecutionStarted.add(remainingExecutionTime);
    int comparison=finishTime.compareTo(physicalTime);
    if (comparison < 0) {
      throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
    }
 else     if (comparison == 0) {
      setTag(currentEventList.timeStamp,currentEventList.microstep);
      _currentlyExecutingStack.pop();
      _physicalTimeExecutionStarted=physicalTime;
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName(getContainer()) + "String_Node_Str"+ physicalTime);
      }
      _setIcon(_getIdleIcon(),false);
      _clearHighlight(_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),false);
      _lastExecutingActor=null;
      executiveDirector.fireAtCurrentTime((Actor)container);
      return _getActorFromEventList((List<PtidesEvent>)currentEventList.contents);
    }
 else {
      Time nextEventOnStackFireTime=_currentlyExecutingStack.peek().remainingExecutionTime;
      Time expectedCompletionTime=nextEventOnStackFireTime.add(_physicalTimeExecutionStarted);
      Time fireAtTime=executiveDirector.fireAt(container,expectedCompletionTime);
      if (!fireAtTime.equals(expectedCompletionTime)) {
        throw new IllegalActionException(executiveDirector,"String_Node_Str" + expectedCompletionTime + "String_Node_Str"+ fireAtTime);
      }
      if (_eventQueue.isEmpty() || !_preemptExecutingActor()) {
        return null;
      }
    }
  }
  if (_eventQueue.isEmpty()) {
    _setIcon(_getIdleIcon(),false);
    return null;
  }
  PtidesEvent eventFromQueue=_getNextSafeEvent();
  if (eventFromQueue == null) {
    return null;
  }
  Time timeStampOfEventFromQueue=eventFromQueue.timeStamp();
  int microstepOfEventFromQueue=eventFromQueue.microstep();
  _trackLastTagConsumedByActor(eventFromQueue);
  List<PtidesEvent> eventsToProcess=_takeAllSameTagEventsFromQueue(eventFromQueue);
  Actor actorToFire=_getNextActorToFireForTheseEvents(eventsToProcess);
  IOPort ioPort=eventFromQueue.ioPort();
  if (ioPort == null) {
    List<IOPort> inPortList=eventFromQueue.actor().inputPortList();
    ioPort=inPortList.get(0);
  }
  _lastSourcePort=ioPort;
  Time executionTime=new Time(this,_getExecutionTime(ioPort));
  if (executionTime.compareTo(_zero) == 0) {
    setTag(timeStampOfEventFromQueue,microstepOfEventFromQueue);
    executiveDirector.fireAtCurrentTime((Actor)container);
    return actorToFire;
  }
 else {
    Time expectedCompletionTime=physicalTime.add(executionTime);
    Time fireAtTime=executiveDirector.fireAt(container,expectedCompletionTime);
    if (!fireAtTime.equals(expectedCompletionTime)) {
      throw new IllegalActionException(actorToFire,executiveDirector,"String_Node_Str" + expectedCompletionTime + "String_Node_Str"+ fireAtTime);
    }
    if (!_currentlyExecutingStack.isEmpty()) {
      DoubleTimedEvent currentEventList=_currentlyExecutingStack.peek();
      Time elapsedTime=physicalTime.subtract(_physicalTimeExecutionStarted);
      currentEventList.remainingExecutionTime=currentEventList.remainingExecutionTime.subtract(elapsedTime);
      if (currentEventList.remainingExecutionTime.compareTo(_zero) < 0) {
        throw new IllegalActionException(this,_getActorFromEventList((List<PtidesEvent>)currentEventList.contents),"String_Node_Str");
      }
      if (_debugging) {
        _debug("String_Node_Str" + _getActorFromEventList((List<PtidesEvent>)currentEventList.contents).getName((NamedObj)container) + "String_Node_Str"+ physicalTime+ "String_Node_Str"+ currentEventList.remainingExecutionTime);
      }
    }
    _currentlyExecutingStack.push(new DoubleTimedEvent(timeStampOfEventFromQueue,microstepOfEventFromQueue,eventsToProcess,executionTime));
    _physicalTimeExecutionStarted=physicalTime;
    _setIcon(_getExecutingIcon(actorToFire),false);
    _lastExecutingActor=actorToFire;
    return null;
  }
}