Program: 74978
Project: 74978
Buggy source:
/** 
 * If it has not already been done, start a thread to read tokens from the <i>input</i> port and store them in the buffer. Then, in the calling thread, if there is at least one token in the buffer, write the first token to the <i>output</i> port.
 * @exception IllegalActionException If an error occurs duringexecuting the process.
 * @exception TerminateProcessException If the process terminationis requested by the director.
 */
public void fire() throws IllegalActionException {
  super.fire();
  final RendezvousDirector director=(RendezvousDirector)getDirector();
  final Thread writeThread=Thread.currentThread();
  if (!(getDirector() instanceof RendezvousDirector)) {
    throw new IllegalActionException(this,"String_Node_Str");
  }
  _postfireReturns=true;
  if (_readThread == null) {
    _readThread=new Thread(getFullName() + "String_Node_Str"){
      public void run(){
        try {
          if (_debugging) {
            _debug("String_Node_Str");
          }
          _exception=null;
          while (!_stopRequested) {
synchronized (director) {
              int capacityValue=((IntToken)capacity.getToken()).intValue();
              while (_buffer.size() >= capacityValue && !_stopRequested) {
                if (_debugging) {
                  _debug("String_Node_Str");
                }
                try {
                  director.threadBlocked(_readThread,null);
                  RendezvousReceiver.waitForChange(director);
                }
  finally {
                  director.threadUnblocked(_readThread,null);
                }
              }
              if (_stopRequested) {
                break;
              }
              if (_debugging) {
                _debug("String_Node_Str");
              }
              Token token=input.get(0);
              _buffer.add(token);
              if (_debugging) {
                _debug("String_Node_Str" + _buffer);
              }
              director.threadUnblocked(writeThread,null);
              director.notifyAll();
            }
          }
        }
 catch (        TerminateProcessException ex) {
          _postfireReturns=false;
        }
catch (        IllegalActionException ex) {
          _exception=ex;
        }
 finally {
          director.removeThread(_readThread);
          if (_debugging) {
            _debug("String_Node_Str");
          }
        }
      }
    }
;
    director.addThread(_readThread);
    _readThread.start();
  }
synchronized (director) {
    if (_exception != null) {
      throw _exception;
    }
    while (_buffer.size() == 0) {
      if (_stopRequested || !_postfireReturns) {
        _postfireReturns=false;
        return;
      }
      if (_debugging) {
        _debug("String_Node_Str");
      }
      try {
        director.threadBlocked(writeThread,null);
        RendezvousReceiver.waitForChange(director);
      }
 catch (      TerminateProcessException ex) {
        _postfireReturns=false;
        return;
      }
 finally {
        director.threadUnblocked(writeThread,null);
      }
      if (_exception != null) {
        throw _exception;
      }
    }
    Token token=(Token)_buffer.get(0);
    if (_debugging) {
      _debug("String_Node_Str" + token);
    }
    if (_exception != null) {
      throw _exception;
    }
    try {
      output.send(0,token);
    }
 catch (    TerminateProcessException e) {
      _postfireReturns=false;
      return;
    }
    if (_exception != null) {
      throw _exception;
    }
    _buffer.remove(0);
    if (_debugging) {
      _debug("String_Node_Str" + _buffer);
    }
  }
}

Fixed version (ground truth):
/** 
 * If it has not already been done, start a thread to read tokens from the <i>input</i> port and store them in the buffer. Then, in the calling thread, if there is at least one token in the buffer, write the first token to the <i>output</i> port.
 * @exception IllegalActionException If an error occurs duringexecuting the process.
 * @exception TerminateProcessException If the process terminationis requested by the director.
 */
public void fire() throws IllegalActionException {
  super.fire();
  final Thread writeThread=Thread.currentThread();
  if (!(getDirector() instanceof RendezvousDirector)) {
    throw new IllegalActionException(this,"String_Node_Str");
  }
  final RendezvousDirector director=(RendezvousDirector)getDirector();
  _postfireReturns=true;
  if (_readThread == null) {
    _readThread=new Thread(getFullName() + "String_Node_Str"){
      public void run(){
        try {
          if (_debugging) {
            _debug("String_Node_Str");
          }
          _exception=null;
          while (!_stopRequested) {
synchronized (director) {
              int capacityValue=((IntToken)capacity.getToken()).intValue();
              while (_buffer.size() >= capacityValue && !_stopRequested) {
                if (_debugging) {
                  _debug("String_Node_Str");
                }
                try {
                  director.threadBlocked(_readThread,null);
                  RendezvousReceiver.waitForChange(director);
                }
  finally {
                  director.threadUnblocked(_readThread,null);
                }
              }
              if (_stopRequested) {
                break;
              }
              if (_debugging) {
                _debug("String_Node_Str");
              }
              Token token=input.get(0);
              _buffer.add(token);
              if (_debugging) {
                _debug("String_Node_Str" + _buffer);
              }
              director.threadUnblocked(writeThread,null);
              director.notifyAll();
            }
          }
        }
 catch (        TerminateProcessException ex) {
          _postfireReturns=false;
        }
catch (        IllegalActionException ex) {
          _exception=ex;
        }
 finally {
          director.removeThread(_readThread);
          if (_debugging) {
            _debug("String_Node_Str");
          }
        }
      }
    }
;
    director.addThread(_readThread);
    _readThread.start();
  }
synchronized (director) {
    if (_exception != null) {
      throw _exception;
    }
    while (_buffer.size() == 0) {
      if (_stopRequested || !_postfireReturns) {
        _postfireReturns=false;
        return;
      }
      if (_debugging) {
        _debug("String_Node_Str");
      }
      try {
        director.threadBlocked(writeThread,null);
        RendezvousReceiver.waitForChange(director);
      }
 catch (      TerminateProcessException ex) {
        _postfireReturns=false;
        return;
      }
 finally {
        director.threadUnblocked(writeThread,null);
      }
      if (_exception != null) {
        throw _exception;
      }
    }
    Token token=(Token)_buffer.get(0);
    if (_debugging) {
      _debug("String_Node_Str" + token);
    }
    if (_exception != null) {
      throw _exception;
    }
    try {
      output.send(0,token);
    }
 catch (    TerminateProcessException e) {
      _postfireReturns=false;
      return;
    }
    if (_exception != null) {
      throw _exception;
    }
    _buffer.remove(0);
    if (_debugging) {
      _debug("String_Node_Str" + _buffer);
    }
    int capacityValue=((IntToken)capacity.getToken()).intValue();
    if (_buffer.size() == capacityValue - 1 && !_stopRequested) {
      director.threadUnblocked(_readThread,null);
      director.notifyAll();
    }
  }
}