@SuppressWarnings("unchecked")
 private boolean write(InputBuffer input) throws IOException {
   if (closed) {
     return false;
   }
   int totalRead = 0;
   final int remain = input.remaining();
   this.nativeReader.reset(input);
   while (remain > totalRead) {
     final int read = deserializer.deserializeKV(nativeReader, tmpOutputKey, tmpOutputValue);
     if (read != 0) {
       totalRead += read;
       writer.write((OK) (tmpOutputKey.v), (OV) (tmpOutputValue.v));
     }
   }
   if (remain != totalRead) {
     throw new IOException("We expect to read " + remain + ", but we actually read: " + totalRead);
   }
   return true;
 }
  public boolean collect(InputBuffer buffer) throws IOException {
    if (closed) {
      return false;
    }

    final ByteBuffer input = buffer.getByteBuffer();
    if (null != asideBuffer && asideBuffer.length() > 0) {
      if (asideBuffer.remaining() > 0) {
        final byte[] output = asideBuffer.getByteBuffer().array();
        final int write = Math.min(asideBuffer.remaining(), input.remaining());
        input.get(output, asideBuffer.position(), write);
        asideBuffer.position(asideBuffer.position() + write);
      }

      if (asideBuffer.remaining() == 0 && asideBuffer.position() > 0) {
        asideBuffer.position(0);
        write(asideBuffer);
        asideBuffer.rewind(0, 0);
      }
    }

    if (input.remaining() == 0) {
      return true;
    }

    if (input.remaining() < KV_HEADER_LENGTH) {
      throw new IOException("incomplete data, input length is: " + input.remaining());
    }
    final int position = input.position();
    final int keyLength = input.getInt();
    final int valueLength = input.getInt();
    input.position(position);
    final int kvLength = keyLength + valueLength + KV_HEADER_LENGTH;
    final int remaining = input.remaining();

    if (kvLength > remaining) {
      if (null == asideBuffer || asideBuffer.capacity() < kvLength) {
        asideBuffer = new InputBuffer(BufferType.HEAP_BUFFER, kvLength);
      }
      asideBuffer.rewind(0, kvLength);

      input.get(asideBuffer.array(), 0, remaining);
      asideBuffer.position(remaining);
    } else {
      write(buffer);
    }
    return true;
  }