docs: private static Buffer[] cloneBufferArray(Buffer[] srcBuffers) {
  
          Buffer[] clonedBuffers = null;
          int i;
          short dataSize;
  
          if (srcBuffers != null) {
              clonedBuffers = new Buffer[srcBuffers.length];
  
              for (i = 0; i < srcBuffers.length; i++)
                  srcBuffers[i].rewind();
  
              /*
               * In order to optimize the transfer we need a type check.
               *
               * Most CPUs support hardware memory transfer for different data
               * types, so it's faster to copy more bytes at once rather
               * than one byte per iteration as in case of ByteBuffer.
               *
               * For example, Intel CPUs support MOVSB (byte transfer), MOVSW
               * (word transfer), MOVSD (double word transfer), MOVSS (32 bit
               * scalar single precision floating point), MOVSQ (quad word
               * transfer) and so on...
               *
               * Type checking may be improved by changing the order in
               * which a buffer is checked against. If it's likely that the
               * expected buffer is of type "ShortBuffer", then it should be
               * checked at first place.
               *
               */
  
              if (srcBuffers[0] instanceof ByteBuffer)
                  // dataSize is 1
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity())
                              .put((ByteBuffer) srcBuffers[i]).rewind();
              else if (srcBuffers[0] instanceof ShortBuffer) {
                  dataSize = Short.SIZE >> 3; // dataSize is 2
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity() * dataSize)
                              .order(ByteOrder.nativeOrder()).asShortBuffer().put((ShortBuffer) srcBuffers[i]).rewind();
              } else if (srcBuffers[0] instanceof IntBuffer) {
                  dataSize = Integer.SIZE >> 3; // dataSize is 4
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity() * dataSize)
                              .order(ByteOrder.nativeOrder()).asIntBuffer().put((IntBuffer) srcBuffers[i]).rewind();
              } else if (srcBuffers[0] instanceof LongBuffer) {
                  dataSize = Long.SIZE >> 3; // dataSize is 8
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity() * dataSize)
                              .order(ByteOrder.nativeOrder()).asLongBuffer().put((LongBuffer) srcBuffers[i]).rewind();
              } else if (srcBuffers[0] instanceof FloatBuffer) {
                  dataSize = Float.SIZE >> 3; // dataSize is 4
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity() * dataSize)
                              .order(ByteOrder.nativeOrder()).asFloatBuffer().put((FloatBuffer) srcBuffers[i]).rewind();
              } else if (srcBuffers[0] instanceof DoubleBuffer) {
                  dataSize = Double.SIZE >> 3; // dataSize is 8
                  for (i = 0; i < srcBuffers.length; i++)
                      clonedBuffers[i] = ByteBuffer.allocateDirect(srcBuffers[i].capacity() * dataSize)
                              .order(ByteOrder.nativeOrder()).asDoubleBuffer().put((DoubleBuffer) srcBuffers[i]).rewind();
              }
  
              for (i = 0; i < srcBuffers.length; i++)
                  srcBuffers[i].rewind();
  
          }
  
          return clonedBuffers;
  
      }