Program: 72853
Project: 72853
Buggy source:
/** 
 * Dequeue the events that have the smallest tag from the event queue. Return their destination actor. Advance the model tag to their tag. If the timestamp of the smallest tag is greater than the stop time then return null. If there are no events in the event queue, and the stopWhenQueueIsEmpty parameter is set to true, then return null. Both cases will have the effect of stopping the simulation. <p> If the stopWhenQueueIsEmpty parameter is false and the queue is empty, then stall the current thread by calling wait() on the _eventQueue until there are new events available.  If the synchronizeToRealTime parameter is true, then this method may suspend the calling thread by using Object.wait(long) to let elapsed real time catch up with the current model time.</p>
 * @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.
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  if (_eventQueue == null) {
    throw new IllegalActionException("String_Node_Str");
  }
  Actor actorToFire=null;
  DEEvent lastFoundEvent=null;
  DEEvent nextEvent=null;
  while (!_stopRequested) {
    if (_stopWhenQueueIsEmpty) {
      if (_eventQueue.isEmpty()) {
        break;
      }
    }
    if (isEmbedded()) {
      if (_eventQueue.isEmpty()) {
        break;
      }
      nextEvent=_eventQueue.get();
      if (nextEvent.timeStamp().compareTo(getModelTime()) < 0) {
        throw new IllegalActionException("String_Node_Str" + nextEvent.timeStamp() + "String_Node_Str"+ nextEvent.microstep()+ "String_Node_Str"+ getModelTime()+ "String_Node_Str"+ _microstep+ "String_Node_Str");
      }
      boolean microstepMatches=true;
      Nameable container=getContainer();
      if (container instanceof CompositeActor) {
        Director executiveDirector=((CompositeActor)container).getExecutiveDirector();
        if (executiveDirector instanceof SuperdenseTimeDirector && !_isTopLevel()) {
          microstepMatches=nextEvent.microstep() <= _microstep;
        }
      }
      int comparison=nextEvent.timeStamp().compareTo(getModelTime());
      if (comparison > 0 || comparison == 0 && !microstepMatches) {
        nextEvent=null;
        break;
      }
    }
 else {
      if (_eventQueue.isEmpty()) {
        if (actorToFire != null || getModelTime().equals(getModelStopTime())) {
          break;
        }
      }
synchronized (_eventQueue) {
        while (_eventQueue.isEmpty() && !_stopRequested && !_stopFireRequested) {
          if (_debugging) {
            _debug("String_Node_Str");
          }
          try {
            workspace().wait(_eventQueue);
          }
 catch (          InterruptedException e) {
            break;
          }
        }
        if (_eventQueue.isEmpty()) {
          return null;
        }
        nextEvent=_eventQueue.get();
      }
    }
    if (actorToFire == null) {
      Time currentTime;
      int depth=0;
      try {
synchronized (_eventQueue) {
          lastFoundEvent=_eventQueue.get();
          currentTime=_consultTimeRegulators(lastFoundEvent.timeStamp());
          if (_synchronizeToRealTime) {
            while (!_stopRequested && !_stopFireRequested) {
              lastFoundEvent=_eventQueue.get();
              currentTime=lastFoundEvent.timeStamp();
              long elapsedTime=System.currentTimeMillis() - _realStartTime;
              double elapsedTimeInSeconds=elapsedTime / 1000.0;
              ptolemy.actor.util.Time elapsed=new ptolemy.actor.util.Time(this,elapsedTimeInSeconds);
              if (currentTime.compareTo(elapsed) <= 0) {
                break;
              }
              long timeToWait=(long)(currentTime.subtract(elapsed).getDoubleValue() * 1000.0);
              if (timeToWait > 0) {
                if (_debugging) {
                  _debug("String_Node_Str" + timeToWait);
                }
                try {
                  depth=_workspace.releaseReadPermission();
                  _eventQueue.wait(timeToWait);
                }
 catch (                InterruptedException ex) {
                  throw new IllegalActionException(this,ex,"String_Node_Str" + "String_Node_Str");
                }
              }
            }
            if (_stopRequested || _stopFireRequested) {
              return null;
            }
          }
        }
      }
  finally {
        if (depth > 0) {
          _workspace.reacquireReadPermission(depth);
        }
      }
synchronized (_eventQueue) {
        lastFoundEvent=_eventQueue.take();
        currentTime=lastFoundEvent.timeStamp();
        actorToFire=lastFoundEvent.actor();
        if (_disabledActors != null && _disabledActors.contains(actorToFire)) {
          if (_debugging) {
            _debug("String_Node_Str",((Nameable)actorToFire).getFullName());
          }
          actorToFire=null;
          continue;
        }
        setModelTime(currentTime);
        _microstep=lastFoundEvent.microstep();
        if (_debugging) {
          _debug("String_Node_Str" + currentTime + "String_Node_Str"+ _microstep+ "String_Node_Str");
        }
      }
      if (currentTime.compareTo(getModelStopTime()) > 0) {
        if (_debugging) {
          _debug("String_Node_Str");
        }
        _exceedStopTime=true;
        return null;
      }
    }
 else {
      if (nextEvent.hasTheSameTagAs(lastFoundEvent) && nextEvent.actor() == actorToFire) {
synchronized (_eventQueue) {
          _eventQueue.take();
        }
      }
 else {
        break;
      }
    }
    if (actorToFire != null && _resourceScheduling) {
      if (_actorsFinished.contains(actorToFire)) {
        _actorsFinished.remove(actorToFire);
      }
 else       if (!_schedule(actorToFire,getModelTime())) {
        Time nextScheduleTime=_nextScheduleTime.get(_schedulerForActor.get(actorToFire)).add(getModelTime());
        if (_actorsInExecution == null) {
          _actorsInExecution=new HashMap();
        }
        _actorsInExecution.put(actorToFire,lastFoundEvent);
        actorToFire=null;
      }
    }
  }
  return actorToFire;
}

Fixed version (ground truth):
/** 
 * Dequeue the events that have the smallest tag from the event queue. Return their destination actor. Advance the model tag to their tag. If the timestamp of the smallest tag is greater than the stop time then return null. If there are no events in the event queue, and the stopWhenQueueIsEmpty parameter is set to true, then return null. Both cases will have the effect of stopping the simulation. <p> If the stopWhenQueueIsEmpty parameter is false and the queue is empty, then stall the current thread by calling wait() on the _eventQueue until there are new events available.  If the synchronizeToRealTime parameter is true, then this method may suspend the calling thread by using Object.wait(long) to let elapsed real time catch up with the current model time.</p>
 * @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.
 */
protected Actor _getNextActorToFire() throws IllegalActionException {
  if (_eventQueue == null) {
    throw new IllegalActionException("String_Node_Str");
  }
  Actor actorToFire=null;
  DEEvent lastFoundEvent=null;
  DEEvent nextEvent=null;
  while (!_stopRequested) {
    if (_stopWhenQueueIsEmpty) {
      if (_eventQueue.isEmpty()) {
        break;
      }
    }
    if (isEmbedded()) {
      if (_eventQueue.isEmpty()) {
        break;
      }
      nextEvent=_eventQueue.get();
      if (nextEvent.timeStamp().compareTo(getModelTime()) < 0) {
        throw new IllegalActionException("String_Node_Str" + nextEvent.timeStamp() + "String_Node_Str"+ nextEvent.microstep()+ "String_Node_Str"+ getModelTime()+ "String_Node_Str"+ _microstep+ "String_Node_Str");
      }
      boolean microstepMatches=true;
      Nameable container=getContainer();
      if (container instanceof CompositeActor) {
        Director executiveDirector=((CompositeActor)container).getExecutiveDirector();
        if (executiveDirector instanceof SuperdenseTimeDirector && !_isTopLevel()) {
          microstepMatches=nextEvent.microstep() <= _microstep;
        }
      }
      int comparison=nextEvent.timeStamp().compareTo(getModelTime());
      if (comparison > 0 || comparison == 0 && !microstepMatches) {
        nextEvent=null;
        break;
      }
    }
 else {
      if (_eventQueue.isEmpty()) {
        if (actorToFire != null || getModelTime().equals(getModelStopTime())) {
          break;
        }
      }
synchronized (_eventQueue) {
        while (_eventQueue.isEmpty() && !_stopRequested && !_stopFireRequested) {
          if (_debugging) {
            _debug("String_Node_Str");
          }
          try {
            workspace().wait(_eventQueue);
          }
 catch (          InterruptedException e) {
            break;
          }
        }
        if (_eventQueue.isEmpty()) {
          return null;
        }
        nextEvent=_eventQueue.get();
      }
    }
    if (actorToFire == null) {
      Time currentTime;
      int depth=0;
      try {
synchronized (_eventQueue) {
          lastFoundEvent=_eventQueue.get();
          currentTime=_consultTimeRegulators(lastFoundEvent.timeStamp());
          if (_synchronizeToRealTime) {
            while (!_stopRequested && !_stopFireRequested) {
              lastFoundEvent=_eventQueue.get();
              currentTime=lastFoundEvent.timeStamp();
              long elapsedTime=System.currentTimeMillis() - _realStartTime;
              double elapsedTimeInSeconds=elapsedTime / 1000.0;
              ptolemy.actor.util.Time elapsed=new ptolemy.actor.util.Time(this,elapsedTimeInSeconds);
              if (currentTime.compareTo(elapsed) <= 0) {
                break;
              }
              long timeToWait=(long)(currentTime.subtract(elapsed).getDoubleValue() * 1000.0);
              if (timeToWait > 0) {
                if (_debugging) {
                  _debug("String_Node_Str" + timeToWait);
                }
                try {
                  depth=_workspace.releaseReadPermission();
                  _eventQueue.wait(timeToWait);
                }
 catch (                InterruptedException ex) {
                  throw new IllegalActionException(this,ex,"String_Node_Str" + "String_Node_Str");
                }
              }
            }
            if (_stopRequested || _stopFireRequested) {
              return null;
            }
          }
        }
      }
  finally {
        if (depth > 0) {
          _workspace.reacquireReadPermission(depth);
        }
      }
synchronized (_eventQueue) {
        lastFoundEvent=_eventQueue.take();
        currentTime=lastFoundEvent.timeStamp();
        actorToFire=lastFoundEvent.actor();
        if (_disabledActors != null && _disabledActors.contains(actorToFire)) {
          if (_debugging) {
            _debug("String_Node_Str",((Nameable)actorToFire).getFullName());
          }
          actorToFire=null;
          continue;
        }
        setModelTime(currentTime);
        _microstep=lastFoundEvent.microstep();
        if (_debugging) {
          _debug("String_Node_Str" + currentTime + "String_Node_Str"+ _microstep+ "String_Node_Str");
        }
      }
      if (currentTime.compareTo(getModelStopTime()) > 0) {
        if (_debugging) {
          _debug("String_Node_Str");
        }
        _exceedStopTime=true;
        return null;
      }
    }
 else {
      if (nextEvent.hasTheSameTagAs(lastFoundEvent) && nextEvent.actor() == actorToFire) {
synchronized (_eventQueue) {
          _eventQueue.take();
        }
      }
 else {
        break;
      }
    }
    if (actorToFire != null && _resourceScheduling) {
      if (_actorsFinished.contains(actorToFire)) {
        _actorsFinished.remove(actorToFire);
      }
 else       if (!_schedule(actorToFire,getModelTime())) {
        Time nextScheduleTime=_nextScheduleTime.get(_schedulerForActor.get(actorToFire)).add(getModelTime());
        if (_actorsInExecution == null) {
          _actorsInExecution=new HashMap();
        }
        List<DEEvent> events=_actorsInExecution.get(actorToFire);
        if (events == null) {
          events=new ArrayList<DEEvent>();
        }
        events.add(lastFoundEvent);
        _actorsInExecution.put(actorToFire,events);
        actorToFire=null;
      }
    }
  }
  return actorToFire;
}