code: public static byte[] copyAllBytesFrom(ByteBuffer bb) {
          if (bb == null) {
              return null;
          }
  
          if (bb.hasArray()) {
              return Arrays.copyOfRange(
                      bb.array(),
                      bb.arrayOffset(),
                      bb.arrayOffset() + bb.limit());
          }
  
          ByteBuffer copy = bb.asReadOnlyBuffer();
          copy.rewind();
  
          byte[] dst = new byte[copy.remaining()];
          copy.get(dst);
          return dst;
      }
docs: Returns a copy of all the bytes from the given <code>ByteBuffer</code>,
  from the beginning to the buffer's limit; or null if the input is null.
  <p>
  The internal states of the given byte buffer will be restored when this
  method completes execution.
  <p>
  When handling <code>ByteBuffer</code> from user's input, it's typical to
  call the {@link #copyBytesFrom(ByteBuffer)} instead of
  {@link #copyAllBytesFrom(ByteBuffer)} so as to account for the position
  of the input <code>ByteBuffer</code>. The opposite is typically true,
  however, when handling <code>ByteBuffer</code> from withint the
  unmarshallers of the low-level clients.