private TCNetworkMessage processPayloadData(TCConnection source, TCByteBuffer[] data)
      throws TCProtocolException {
    for (int i = 0; i < data.length; i++) {
      final TCByteBuffer buffer = data[i];

      if (!buffer.hasRemaining()) {
        buffer.flip();
        dataBytesNeeded -= buffer.limit();
        bufferIndex++;

        if (dataBytesNeeded < 0) {
          throw new TCProtocolException("More data in buffers than expected");
        }
      } else {
        break;
      }
    }

    if (0 == dataBytesNeeded) {
      if (bufferIndex != dataBuffers.length) {
        throw new TCProtocolException("Not all buffers consumed");
      }

      // message is complete!
      TCNetworkMessage msg = createMessage(source, header, dataBuffers);

      if (logger.isDebugEnabled()) {
        logger.debug("Message complete on connection " + source + ": " + msg.toString());
      }

      return msg;
    }

    Assert.eval(dataBytesNeeded > 0);

    // data portion not done, try again later
    return null;
  }