private ByteBuffer convertToByteBuffer(ByteBuf buf) {
    if (buf == null) {
      return null;
    }
    int bufferCount = buf.nioBufferCount();
    switch (bufferCount) {
      case 0:
        return EMPTY_BYTE_BUFFER;
      case 1:
        ByteBuffer buffer = buf.nioBuffer();
        buf.readerIndex(buf.readerIndex() + buf.readableBytes());
        return buffer;
      default:
        ByteBuffer byteBuffer = ByteBuffer.allocate(buf.readableBytes());
        // This would also update the readerIndex for buf.
        buf.readBytes(byteBuffer);
        byteBuffer.flip();
        return byteBuffer;
    }
  }
Convert the {@link ByteBuf} to a {@link ByteBuffer}. It will change the {@link ByteBuf#readerIndex()} for the given
{@code buf}.
@param buf The {@link ByteBuf}'s data that would be converted to a {@link ByteBuffer}.
@return A {@link ByteBuffer} that contains the same data as the given {@code buf}.
ambry-commons/src/main/java/com/github/ambry/commons/ByteBufferAsyncWritableChannel.java