code: @Override
    public boolean processBytesFromPeer(ByteBuffer bytes) throws GeneralSecurityException {
      // If we're the client and we haven't given an output frame, we shouldn't be processing any
      // bytes.
      if (outputFrame == null && isClient) {
        return true;
      }
      // If we already have bytes to write, just return.
      if (outputFrame != null && outputFrame.hasRemaining()) {
        return true;
      }
      int remaining = bytes.remaining();
      // Call handshaker service to proceess the bytes.
      if (outputFrame == null) {
        checkState(!isClient, "Client handshaker should not process any frame at the beginning.");
        outputFrame = handshaker.startServerHandshake(bytes);
      } else {
        outputFrame = handshaker.next(bytes);
      }
      // If handshake has finished or we already have bytes to write, just return true.
      if (handshaker.isFinished() || outputFrame.hasRemaining()) {
        return true;
      }
      // We have done processing input bytes, but no bytes to write. Thus we need more data.
      if (!bytes.hasRemaining()) {
        return false;
      }
      // There are still remaining bytes. Thus we need to continue processing the bytes.
      // Prevent infinite loop by checking some bytes are consumed by handshaker.
      checkState(bytes.remaining() < remaining, "Handshaker did not consume any bytes.");
      return processBytesFromPeer(bytes);
    }
docs: Process the bytes received from the peer.
  
  @param bytes The buffer containing the handshake bytes from the peer.
  @return true, if the handshake has all the data it needs to process and false, if the method
  must be called again to complete processing.