Program: 4126
Project: 4126
Buggy source:
public int read(ByteBuffer dst) throws IOException {
  if (shutdown)   throw new ClosedChannelException();
  if (taskScheduled)   return 0;
  int transferred=0;
  if (readOutgoing != null && readOutgoing.position() > 0) {
    transferred+=BufferUtils.transfer(readOutgoing,dst);
    if (readOutgoing.hasRemaining()) {
      LOG.debug("String_Node_Str");
      return transferred;
    }
  }
  while (true) {
    if (firstReadDone.get() && !dst.hasRemaining() && engine.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
      LOG.debug("String_Node_Str");
      return transferred;
    }
    int read=-1;
    while (readIncoming.hasRemaining() && (read=readSink.read(readIncoming)) > 0)     ;
    if (read == -1 && readIncoming.position() == 0) {
      LOG.debug("String_Node_Str");
      return -1;
    }
    if (readIncoming.position() == 0) {
      LOG.debug("String_Node_Str");
      return 0;
    }
    readIncoming.flip();
    SSLEngineResult result=engine.unwrap(readIncoming,dst);
    readProduced+=result.bytesProduced();
    readConsumed+=result.bytesConsumed();
    transferred+=result.bytesProduced();
    SSLEngineResult.Status status=result.getStatus();
    if (status == Status.BUFFER_OVERFLOW) {
      if (readOutgoing == null) {
synchronized (initLock) {
          if (!shutdown)           readOutgoing=byteBufferCache.getHeap(engine.getSession().getPacketBufferSize());
        }
      }
      result=engine.unwrap(readIncoming,readOutgoing);
      readProduced+=result.bytesProduced();
      readConsumed+=result.bytesConsumed();
      status=result.getStatus();
      if (status == Status.BUFFER_OVERFLOW)       throw new IllegalStateException("String_Node_Str" + readOutgoing + "String_Node_Str"+ readIncoming);
      transferred+=BufferUtils.transfer(readOutgoing,dst);
    }
    firstReadDone.set(true);
    if (readIncoming.hasRemaining()) {
      readDataLeft=true;
      readIncoming.compact();
    }
 else {
      readDataLeft=false;
      readIncoming.clear();
    }
    if (LOG.isDebugEnabled())     LOG.debug("String_Node_Str" + result + "String_Node_Str"+ transferred);
    if (status == Status.BUFFER_UNDERFLOW) {
      if (transferred == 0 && read == -1) {
        LOG.debug("String_Node_Str");
        return -1;
      }
 else {
        return transferred;
      }
    }
    if (status == Status.CLOSED) {
      if (transferred == 0)       return -1;
 else       return transferred;
    }
    if (!processHandshakeResult(true,false,result.getHandshakeStatus()))     return transferred;
  }
}

Fixed version (ground truth):
public int read(ByteBuffer dst) throws IOException {
  if (shutdown)   throw new ClosedChannelException();
  if (taskScheduled)   return 0;
  int transferred=0;
  if (readOutgoing != null && readOutgoing.position() > 0) {
    transferred+=BufferUtils.transfer(readOutgoing,dst);
    if (readOutgoing.hasRemaining()) {
      LOG.debug("String_Node_Str");
      return transferred;
    }
  }
  while (true) {
    if (firstReadDone.get() && !dst.hasRemaining() && engine.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
      LOG.debug("String_Node_Str");
      return transferred;
    }
    int read=-1;
    while (readIncoming.hasRemaining() && (read=readSink.read(readIncoming)) > 0)     ;
    if (read == -1 && readIncoming.position() == 0) {
      LOG.debug("String_Node_Str");
      return -1;
    }
    if (readIncoming.position() == 0) {
      LOG.debug("String_Node_Str");
      return 0;
    }
    readIncoming.flip();
    SSLEngineResult result=engine.unwrap(readIncoming,dst);
    readProduced+=result.bytesProduced();
    readConsumed+=result.bytesConsumed();
    transferred+=result.bytesProduced();
    SSLEngineResult.Status status=result.getStatus();
    if (status == Status.BUFFER_OVERFLOW) {
      if (readOutgoing == null) {
synchronized (initLock) {
          if (!shutdown)           readOutgoing=byteBufferCache.getHeap(engine.getSession().getApplicationBufferSize());
        }
      }
      result=engine.unwrap(readIncoming,readOutgoing);
      readProduced+=result.bytesProduced();
      readConsumed+=result.bytesConsumed();
      status=result.getStatus();
      if (status == Status.BUFFER_OVERFLOW)       throw new IllegalStateException("String_Node_Str" + readOutgoing + "String_Node_Str"+ readIncoming+ "String_Node_Str"+ engine.getSession().getPacketBufferSize()+ "String_Node_Str"+ engine.getSession().getApplicationBufferSize());
      transferred+=BufferUtils.transfer(readOutgoing,dst);
    }
    firstReadDone.set(true);
    if (readIncoming.hasRemaining()) {
      readDataLeft=true;
      readIncoming.compact();
    }
 else {
      readDataLeft=false;
      readIncoming.clear();
    }
    if (LOG.isDebugEnabled())     LOG.debug("String_Node_Str" + result + "String_Node_Str"+ transferred);
    if (status == Status.BUFFER_UNDERFLOW) {
      if (transferred == 0 && read == -1) {
        LOG.debug("String_Node_Str");
        return -1;
      }
 else {
        return transferred;
      }
    }
    if (status == Status.CLOSED) {
      if (transferred == 0)       return -1;
 else       return transferred;
    }
    if (!processHandshakeResult(true,false,result.getHandshakeStatus()))     return transferred;
  }
}