Program: 72347
Project: 72347
Buggy source:
/** 
 * If an input is available and either it equals zero or it has crossed zero from the most recently seen input, then output 0.0; otherwise, if an input available and that input is a   {@link SmoothToken} with non-zeroderivatives, then predict the time at which a zero crossing will occur and request a refiring at that time; Otherwise, if no input is available and current time matches the time of a previous refiring request, then produce the output 0.0.
 * @exception IllegalActionException If sending an output fails.
 */
@Override public void fire() throws IllegalActionException {
  super.fire();
  Time currentTime=getDirector().getModelTime();
  if (_debugging) {
    _debug("String_Node_Str" + currentTime);
  }
  DoubleToken inputToken=null;
  if (input.hasNewToken(0)) {
    inputToken=(DoubleToken)input.get(0);
    if (_debugging) {
      _debug("String_Node_Str" + inputToken);
    }
  }
  if (inputToken == null && currentTime.equals(_lastFireAtTime)) {
    if (_previousInput != null) {
      SmoothToken projectedToNow=((SmoothToken)_previousInput).extrapolate(currentTime);
      inputToken=new SmoothToken(0.0,currentTime,projectedToNow.derivativeValues());
      if (_debugging) {
        _debug("String_Node_Str" + inputToken);
      }
    }
  }
  if (inputToken instanceof SmoothToken) {
    double inputValue=inputToken.doubleValue();
    if (_previousInput != null) {
      double previousValue=_previousInput.doubleValue();
      boolean inputIsRising=inputValue >= 0.0 && previousValue < 0.0;
      boolean inputIsFalling=inputValue <= 0.0 && previousValue > 0.0;
      if (_detectFallingCrossing && inputIsFalling || _detectRisingCrossing && inputIsRising) {
        output.send(0,value.getToken());
        if (_debugging) {
          _debug("String_Node_Str");
        }
      }
    }
    Time future=null;
    double[] derivatives=((SmoothToken)inputToken).derivativeValues();
    if (derivatives != null) {
      if (derivatives.length == 1 || (derivatives.length == 2 && derivatives[1] == 0.0) || (derivatives.length > 2 && derivatives[1] == 0.0 && derivatives[2] == 0.0)) {
        if (_detectRisingCrossing && inputValue < 0.0 && derivatives[0] > 0.0 || _detectFallingCrossing && inputValue > 0.0 && derivatives[0] < 0.0) {
          future=currentTime.add(-inputValue / derivatives[0]);
        }
      }
 else       if (derivatives.length == 2 || (derivatives.length > 2 && derivatives[2] == 0.0)) {
        double delta=PolynomialRoot.findMinimumPositiveRoot2(derivatives[1] / 2.0,derivatives[0],inputValue);
        if (delta >= _errorTolerance && delta != Double.POSITIVE_INFINITY) {
          future=currentTime.add(delta);
        }
      }
 else       if (derivatives.length >= 3) {
        double delta=PolynomialRoot.findMinimumPositiveRoot3(derivatives[2] / 6.0,derivatives[1] / 2.0,derivatives[0],inputValue,_errorTolerance,0.0);
        if (delta >= _errorTolerance && delta != Double.POSITIVE_INFINITY) {
          future=currentTime.add(delta);
        }
      }
    }
    if (future != null) {
      if (_lastFireAtTime == null || Math.abs(future.subtractToDouble(_lastFireAtTime)) >= _errorTolerance) {
        if (_lastFireAtTime != null) {
          if (_debugging) {
            _debug("String_Node_Str" + _lastFireAtTime);
          }
          ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
        }
        getDirector().fireAt(this,future);
        _lastFireAtTime=future;
      }
    }
 else {
      if (_lastFireAtTime != null) {
        if (_debugging) {
          _debug("String_Node_Str" + _lastFireAtTime);
        }
        ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
        _lastFireAtTime=null;
      }
    }
  }
 else {
    if (_lastFireAtTime != null) {
      if (_debugging) {
        _debug("String_Node_Str" + _lastFireAtTime);
      }
      ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
    }
    _lastFireAtTime=null;
  }
  _previousInput=(SmoothToken)inputToken;
}

Fixed version (ground truth):
/** 
 * If an input is available and either it equals zero or it has crossed zero from the most recently seen input, then output 0.0; otherwise, if an input available and that input is a   {@link SmoothToken} with non-zeroderivatives, then predict the time at which a zero crossing will occur and request a refiring at that time; Otherwise, if no input is available and current time matches the time of a previous refiring request, then produce the output 0.0.
 * @exception IllegalActionException If sending an output fails.
 */
@Override public void fire() throws IllegalActionException {
  super.fire();
  Time currentTime=getDirector().getModelTime();
  if (_debugging) {
    _debug("String_Node_Str" + currentTime);
  }
  DoubleToken inputToken=null;
  if (input.hasNewToken(0)) {
    inputToken=(DoubleToken)input.get(0);
    if (_debugging) {
      _debug("String_Node_Str" + inputToken);
    }
  }
  if (inputToken == null && currentTime.equals(_lastFireAtTime)) {
    if (_previousInput != null) {
      SmoothToken projectedToNow=((SmoothToken)_previousInput).extrapolate(currentTime);
      inputToken=new SmoothToken(0.0,currentTime,projectedToNow.derivativeValues());
      if (_debugging) {
        _debug("String_Node_Str" + inputToken);
      }
    }
  }
  if (inputToken instanceof SmoothToken) {
    final double targetValue=_level;
    final double inputValue=inputToken.doubleValue();
    if (_previousInput != null) {
      double previousValue=_previousInput.doubleValue();
      boolean inputIsRising=inputValue >= targetValue && previousValue < targetValue;
      boolean inputIsFalling=inputValue <= targetValue && previousValue > targetValue;
      if (_detectFallingCrossing && inputIsFalling || _detectRisingCrossing && inputIsRising) {
        output.send(0,value.getToken());
        if (_debugging) {
          _debug("String_Node_Str");
        }
      }
    }
    Time future=null;
    double[] derivatives=((SmoothToken)inputToken).derivativeValues();
    if (derivatives != null) {
      if (derivatives.length == 1 || (derivatives.length == 2 && derivatives[1] == 0.0) || (derivatives.length > 2 && derivatives[1] == 0.0 && derivatives[2] == 0.0)) {
        if (_detectRisingCrossing && inputValue < targetValue && derivatives[0] > 0.0 || _detectFallingCrossing && inputValue > targetValue && derivatives[0] < 0.0) {
          future=currentTime.add((targetValue - inputValue) / derivatives[0]);
        }
      }
 else       if (derivatives.length == 2 || (derivatives.length > 2 && derivatives[2] == 0.0)) {
        double delta=PolynomialRoot.findMinimumPositiveRoot2(derivatives[1] / 2.0,derivatives[0],inputValue - targetValue);
        if (delta >= _errorTolerance && delta != Double.POSITIVE_INFINITY) {
          future=currentTime.add(delta);
        }
      }
 else       if (derivatives.length >= 3) {
        double delta=PolynomialRoot.findMinimumPositiveRoot3(derivatives[2] / 6.0,derivatives[1] / 2.0,derivatives[0],inputValue - targetValue,_errorTolerance,0.0);
        if (delta >= _errorTolerance && delta != Double.POSITIVE_INFINITY) {
          future=currentTime.add(delta);
        }
      }
    }
    if (future != null) {
      if (_lastFireAtTime == null || Math.abs(future.subtractToDouble(_lastFireAtTime)) >= _errorTolerance) {
        if (_lastFireAtTime != null) {
          if (_debugging) {
            _debug("String_Node_Str" + _lastFireAtTime);
          }
          ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
        }
        getDirector().fireAt(this,future);
        _lastFireAtTime=future;
      }
    }
 else {
      if (_lastFireAtTime != null) {
        if (_debugging) {
          _debug("String_Node_Str" + _lastFireAtTime);
        }
        ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
        _lastFireAtTime=null;
      }
    }
  }
 else {
    if (_lastFireAtTime != null) {
      if (_debugging) {
        _debug("String_Node_Str" + _lastFireAtTime);
      }
      ((DEDirector)getDirector()).cancelFireAt(this,_lastFireAtTime);
    }
    _lastFireAtTime=null;
  }
  _previousInput=(SmoothToken)inputToken;
}