public static void write(DataOutputStream out, SoMessage so) throws IOException {
    out.writeUTF(so.getName());
    out.writeInt(so.getVersion());
    out.writeInt(so.isPersist() ? 2 : 0);
    out.writeInt(so.getUnknown());
    ArrayList<SoEvent> events = so.getEvents();

    for (int i = 0; i < events.size(); i++) {
      SoEvent event = events.get(i);
      out.writeByte(event.getKind());
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      SoEvent.write(new DataOutputStream(bos), event);
      byte[] data = bos.toByteArray();
      out.writeInt(data.length);
      out.write(data);
    }
  }
  public static SoMessage read(DataInputStream in) throws IOException, AmfException {
    String name = in.readUTF();
    int version = in.readInt();
    boolean persist = (in.readInt() == 2);
    int unknown = in.readInt();
    ArrayList<SoEvent> events = new ArrayList<SoEvent>();

    while (true) {
      int kind;
      try {
        kind = in.readByte() & 0xFF;
      } catch (EOFException e) {
        break;
      }
      int size = in.readInt();
      SoEvent event = SoEvent.read(in, kind, size);
      if (event != null) {
        events.add(event);
      }
    }

    return new SoMessage(name, version, persist, unknown, events);
  }