Program: 82742
Project: 82742
Buggy source:
protected String readResponse(final boolean sendErrorAsResponse,long timeout) throws IOException {
  final StringBuffer response=new StringBuffer();
  final IOException[] exc=new IOException[1];
  final boolean[] done=new boolean[1];
  Runnable r=new Runnable(){
    public void run(){
      try {
        int c;
        while ((c=_in.read()) != -1) {
          response.append((char)c);
          if (response.length() >= PROMPT.length() && response.substring(response.length() - PROMPT.length(),response.length()).equals(PROMPT)) {
            response.setLength(response.length() - PROMPT.length());
            break;
          }
        }
        if (_errors.length() > 0) {
          if (sendErrorAsResponse) {
            response.append(_errors);
            _errors.setLength(0);
          }
 else {
            throw new IOException(chomp(_errors).toString());
          }
        }
        chomp(response);
        done[0]=true;
      }
 catch (      IOException e) {
        exc[0]=e;
      }
    }
  }
;
  Thread reader=null;
  if (timeout == 0) {
    r.run();
  }
 else {
    reader=new Thread(r);
    reader.start();
    try {
      reader.join(timeout);
    }
 catch (    InterruptedException e) {
    }
  }
  updateLastCommandTime();
  if (exc[0] != null) {
    throw exc[0];
  }
 else   if (!done[0]) {
    if (reader != null && reader.isAlive()) {
      reader.stop();
    }
    throw new IOException("String_Node_Str" + getHost());
  }
 else {
    if ("String_Node_Str".equals(response)) {
      Message.info("String_Node_Str" + getHost() + "String_Node_Str");
      closeConnection();
      throw new IOException("String_Node_Str" + getHost());
    }
    Message.debug("String_Node_Str" + response + "String_Node_Str"+ getHost());
    return response.toString();
  }
}

Fixed version (ground truth):
protected synchronized String readResponse(final boolean sendErrorAsResponse,long timeout) throws IOException {
  final StringBuffer response=new StringBuffer();
  final IOException[] exc=new IOException[1];
  final boolean[] done=new boolean[1];
  Runnable r=new Runnable(){
    public void run(){
synchronized (VsftpRepository.this) {
        try {
          int c;
          boolean getPrompt=false;
          for (int attempts=0; !getPrompt && attempts < 5; attempts++) {
            while ((c=_in.read()) != -1) {
              attempts=0;
              response.append((char)c);
              if (response.length() >= PROMPT.length() && response.substring(response.length() - PROMPT.length(),response.length()).equals(PROMPT)) {
                response.setLength(response.length() - PROMPT.length());
                getPrompt=true;
                break;
              }
            }
            if (!getPrompt) {
              try {
                Thread.sleep(50);
              }
 catch (              InterruptedException e) {
                break;
              }
            }
          }
          if (getPrompt) {
            if (_errorsLastUpdateTime == 0) {
              _errorsLastUpdateTime=_lastCommand;
            }
            while ((System.currentTimeMillis() - _errorsLastUpdateTime) < 50) {
              try {
                Thread.sleep(30);
              }
 catch (              InterruptedException e) {
                break;
              }
            }
          }
          if (_errors.length() > 0) {
            if (sendErrorAsResponse) {
              response.append(_errors);
              _errors.setLength(0);
            }
 else {
              throw new IOException(chomp(_errors).toString());
            }
          }
          chomp(response);
          done[0]=true;
        }
 catch (        IOException e) {
          exc[0]=e;
        }
 finally {
          VsftpRepository.this.notify();
        }
      }
    }
  }
;
  Thread reader=null;
  if (timeout == 0) {
    r.run();
  }
 else {
    reader=new Thread(r);
    reader.start();
    try {
      wait(timeout);
    }
 catch (    InterruptedException e) {
    }
  }
  updateLastCommandTime();
  if (exc[0] != null) {
    throw exc[0];
  }
 else   if (!done[0]) {
    if (reader != null && reader.isAlive()) {
      reader.interrupt();
      for (int i=0; i < 5 && reader.isAlive(); i++) {
        try {
          Thread.sleep(100);
        }
 catch (        InterruptedException e) {
          break;
        }
      }
      if (reader.isAlive()) {
        reader.stop();
      }
    }
    throw new IOException("String_Node_Str" + getHost());
  }
 else {
    if ("String_Node_Str".equals(response)) {
      Message.info("String_Node_Str" + getHost() + "String_Node_Str");
      closeConnection();
      throw new IOException("String_Node_Str" + getHost());
    }
    Message.debug("String_Node_Str" + response + "String_Node_Str"+ getHost());
    return response.toString();
  }
}