private static byte[] receive(
      final int bytesToReceive,
      final NioFilter filter,
      final SocketChannel channel,
      final ByteBuffer peerNetData) throws IOException {
    final byte[] received = new byte[bytesToReceive];
    // peerNetData in write mode
    peerNetData.flip();
    // peerNetData in read mode
    int pos = 0;
    while (pos < bytesToReceive) {
      /*
       * On first iteration unwrap() is called before the channel is read. This is necessary
       * since a previous call to this method (receive()) could have left data in the filter
       * and there might not be any more data coming on the channel (ever).
       *
       * If no data was already held in the filter's buffer, and peerNetData was empty
       * before calling unwrap() then the buffer returned by unwrap will be empty. But before
       * we start the second loop iteration, we'll read (from the channel into peerNetData).
       *
       * The filter's unwrap() method takes peerNetData in read mode and when the method returns
       * the buffer is in write mode (ready for us to add data to it if needed).
       */
      try (final ByteBufferSharing appDataSharing = filter.unwrap(peerNetData)) {
        // peerNetData in write mode
        final ByteBuffer appData = appDataSharing.getBuffer();
        // appData in write mode
        appData.flip();
        // appData in read mode
        if (appData.hasRemaining()) {
          final int newBytes = Math.min(appData.remaining(), received.length - pos);
          assert pos + newBytes <= received.length;
          appData.get(received, pos, newBytes);
          pos += newBytes;
        } else {
          channel.read(peerNetData);
        }
        peerNetData.flip();
        // peerNetData in read mode ready for filter unwrap() call
        appData.compact();
        // appData in write mode ready for filter unwrap() call
      }
    }
    peerNetData.compact();
    // peerNetData in write mode
    return received;
  }
This method is trying to do what Connection readMessages() and processInputBuffer() do
together.

Note well: peerNetData may contain content on entry to this method. Also the filter's
buffers (e.g. the buffer returned by unwrap) may already contain data from previous
calls to unwrap().

@param peerNetData will be in write mode on entry and may already contain content
geode-core/src/integrationTest/java/org/apache/geode/internal/net/NioSslEngineKeyUpdateTest.java