code: public ByteBuffer copy(int offset, int length, int capacity) {
  
          // if not copying any data, just return an empty buffer
          if (length == 0) {
              return new ByteBuffer(1);
          }
  
          // validate offset, length ok
          ByteBuffer.checkOffsetLength(size(), offset, length);
  
          // is the capacity large enough?
          if (capacity < length) {
              throw new IllegalArgumentException("Capacity must be large enough to hold copied data of size=" + length);
          }
  
          // create a new ByteBuffer with enough capacity
          ByteBuffer copyBuffer = new ByteBuffer(capacity);
  
          // initialize everything now
          // copy this buffer's data into the target buffer -- already allocated memory
          this.toArray(offset, length, copyBuffer.buffer, 0);
          // setup other variables to be correct position now
          copyBuffer.currentBufferSize = length;
          copyBuffer.currentReadPosition = 0;
          copyBuffer.currentWritePosition = length;
  
          return copyBuffer;
      }
docs: Most efficient copy of this <code>ByteBuffer</code>.  The internal buffer
  is copied to the new ByteBuffer using either 1 or 2 calls to System.arraycopy().
  @param offset The offset in the buffer to start from
  @param length The length from the offset
  @param capacity The capacity of the new ByteBuffer. Must be >= this ByteBuffer's size()
  @return The new ByteBuffer with copied data