protected void unpackFrameData(byte[] bytes) throws InvalidDataException {
    ByteBuffer bb = ByteBuffer.wrap(bytes);

    id = ByteBufferUtils.extractNullTerminatedString(bb);

    byte flags = bb.get();
    if ((flags & 0x01) == 0x01) {
      isRoot = true;
    }
    if ((flags & 0x02) == 0x02) {
      isOrdered = true;
    }

    int childCount = bb.get(); // TODO: 0xFF -> int = 255; byte = -128;

    children = new String[childCount];

    for (int i = 0; i < childCount; i++) {
      children[i] = ByteBufferUtils.extractNullTerminatedString(bb);
    }

    for (int offset = bb.position(); offset < bytes.length; ) {
      ID3v2Frame frame = new ID3v2Frame(bytes, offset);
      offset += frame.getLength();
      subframes.add(frame);
    }
  }
 @Override
 protected int getLength() {
   int length = 3;
   if (id != null) length += id.length();
   if (children != null) {
     length += children.length;
     for (String child : children) {
       length += child.length();
     }
   }
   if (subframes != null) {
     for (ID3v2Frame frame : subframes) {
       length += frame.getLength();
     }
   }
   return length;
 }
  protected byte[] packFrameData() {
    ByteBuffer bb = ByteBuffer.allocate(getLength());
    bb.put(id.getBytes());
    bb.put((byte) 0);
    bb.put(getFlags());
    bb.put((byte) children.length);

    for (String child : children) {
      bb.put(child.getBytes());
      bb.put((byte) 0);
    }

    for (ID3v2Frame frame : subframes) {
      try {
        bb.put(frame.toBytes());
      } catch (NotSupportedException e) {
        e.printStackTrace();
      }
    }
    return bb.array();
  }