Program: 73143
Project: 73143
Buggy source:
/** 
 * Schedule a new actor for execution and return the next time this scheduler has to perform a reschedule.
 * @param actor The actor to be scheduled.
 * @param currentPlatformTime The current platform time.
 * @return Relative time when this Scheduler has to be executedagain.
 * @throws IllegalActionException Thrown if actor paramaters suchas execution time or priority cannot be read.
 */
@Override public Time schedule(Actor actor,Time currentPlatformTime) throws IllegalActionException {
  _lastActorFinished=false;
  event(this,currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
  event(this,currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
  Time executionTime=null;
  Double executionTimeDouble=_executionTimes.get(actor);
  if (executionTimeDouble == null) {
    executionTime=getTime(0.0);
  }
 else {
    executionTime=getTime(executionTimeDouble);
  }
  Time remainingTime=null;
  if (_currentlyExecuting.size() == 0) {
    scheduleNewActor(actor,currentPlatformTime,executionTime);
    remainingTime=executionTime;
  }
 else {
    Actor executing=_currentlyExecuting.peek();
    Time lasttime=_lastTimeScheduled.get(executing);
    Time timePassed=currentPlatformTime.subtract(lasttime);
    remainingTime=_remainingTimes.get(executing).subtract(timePassed);
    _remainingTimes.put(executing,remainingTime);
    _lastTimeScheduled.put(executing,currentPlatformTime);
    if (!_currentlyExecuting.contains(actor) && executing != actor) {
      int executingPriority=_getPriority(executing);
      int newActorPriority=_getPriority(actor);
      if (newActorPriority < executingPriority) {
        remainingTime=executionTime;
        event(executing,currentPlatformTime.getDoubleValue(),ExecutionEventType.PREEMPTED);
        scheduleNewActor(actor,currentPlatformTime,executionTime);
      }
    }
 else {
      _lastTimeScheduled.put(actor,currentPlatformTime);
    }
  }
  if (remainingTime.getDoubleValue() == 0.0 && _currentlyExecuting.peek() == actor) {
    event(_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
    _remainingTimes.put(_currentlyExecuting.peek(),null);
    _currentlyExecuting.pop();
    if (_currentlyExecuting.size() > 0) {
      remainingTime=_remainingTimes.get(_currentlyExecuting.peek());
      event(_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
    }
    _lastActorFinished=true;
  }
  return remainingTime;
}

Fixed version (ground truth):
/** 
 * Schedule a new actor for execution and return the next time this scheduler has to perform a reschedule.
 * @param actor The actor to be scheduled.
 * @param currentPlatformTime The current platform time.
 * @return Relative time when this Scheduler has to be executedagain.
 * @throws IllegalActionException Thrown if actor paramaters suchas execution time or priority cannot be read.
 */
@Override public Time schedule(Actor actor,Time currentPlatformTime) throws IllegalActionException {
  _lastActorFinished=false;
  event(this,currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
  event(this,currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
  Time executionTime=null;
  Double executionTimeDouble=_executionTimes.get(actor);
  if (executionTimeDouble == null) {
    executionTime=getTime(0.0);
  }
 else {
    executionTime=getTime(executionTimeDouble);
  }
  Time remainingTime=null;
  if (_currentlyExecuting.size() == 0) {
    scheduleNewActor(actor,currentPlatformTime,executionTime);
    remainingTime=executionTime;
  }
 else {
    Actor executing=_currentlyExecuting.peek();
    Time lasttime=_lastTimeScheduled.get(executing);
    Time timePassed=currentPlatformTime.subtract(lasttime);
    remainingTime=_remainingTimes.get(executing).subtract(timePassed);
    if (remainingTime.getDoubleValue() < 0) {
      throw new IllegalActionException("String_Node_Str");
    }
    _remainingTimes.put(executing,remainingTime);
    if (!_currentlyExecuting.contains(actor) && executing != actor) {
      int executingPriority=_getPriority(executing);
      int newActorPriority=_getPriority(actor);
      if (newActorPriority < executingPriority) {
        remainingTime=executionTime;
        event(executing,currentPlatformTime.getDoubleValue(),ExecutionEventType.PREEMPTED);
        scheduleNewActor(actor,currentPlatformTime,executionTime);
      }
    }
    for (    Actor preemptedActor : _currentlyExecuting) {
      _lastTimeScheduled.put(preemptedActor,currentPlatformTime);
    }
  }
  if (remainingTime.getDoubleValue() == 0.0 && _currentlyExecuting.peek() == actor) {
    event(_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.STOP);
    _remainingTimes.put(_currentlyExecuting.peek(),null);
    _currentlyExecuting.pop();
    if (_currentlyExecuting.size() > 0) {
      remainingTime=_remainingTimes.get(_currentlyExecuting.peek());
      event(_currentlyExecuting.peek(),currentPlatformTime.getDoubleValue(),ExecutionEventType.START);
    }
    _lastActorFinished=true;
  }
  return remainingTime;
}