@Override
  public void format(AssociationMessage message, ByteBuffer bb) {
    if (null == message) {
      throw new IllegalStateException("No ApplicationMessage set");
    }
    setType(message.getType());

    ByteBuffer bbAppMessage = ByteBuffer.allocate(5000);
    message.format(bbAppMessage);
    presentationLength.setLength(
        bbAppMessage.position()
            + message.getPresentationHeader().length
            + message.getPresentationTrailer().length);
    length.setLength(
        presentationLength.getByteCount() + sessionLength() + presentationLength.getLength());
    bbAppMessage.flip();

    Bits.putUnsignedByte(bb, type.asShort());
    length.format(bb);

    LengthInformation li = new LengthInformation();

    for (ParameterIdentifier pi : parameterIdentifiers) {
      Bits.putUnsignedByte(bb, pi.id);
      li.setLength(pi.data.length);
      li.format(bb);
      bb.put(pi.data);
    }

    presentationLength.format(bb);
    bb.put(message.getPresentationHeader());
    bb.put(bbAppMessage);
    bb.put(message.getPresentationTrailer());
  }
  @Override
  public AssociationMessage parse(ByteBuffer bb) {
    // Type and length are the session header
    type = AssociationMessageType.valueOf(Bits.getUnsignedByte(bb));
    length.parse(bb);
    long end_pos = bb.position() + length.getLength();

    LengthInformation li = new LengthInformation();
    parameterIdentifiers.clear();

    // Reads the session data as [identifier, length, payload]
    short pi = Bits.getUnsignedByte(bb);

    //
    while (pi != 0xC1 && bb.position() < end_pos) {
      li.parse(bb);
      log.trace("Parameter Identifier:" + Integer.toHexString(pi));
      byte[] bytes = new byte[(int) li.getLength()];
      bb.get(bytes);
      parameterIdentifiers.add(new ParameterIdentifier(pi, bytes));
      if (bb.position() < end_pos) {
        pi = Bits.getUnsignedByte(bb);
      }
    }
    // Presentation header starts with 0xC1 followed by a length info
    if (0xC1 == pi && bb.position() < end_pos) {
      li.parse(bb);
    }

    AssociationMessage message = buildMessage(getType());

    if (null == message) {
      log.warn("Unimplemented message type:" + getType());
    } else {
      message.advancePastPresentationHeader(bb);
      message.parse(bb);
    }
    bb.position(bb.position() + message.getPresentationTrailer().length);
    return message;
  }