@Override
  public User readFrom(ProtoStreamReader reader) throws IOException {
    int id = reader.readInt("id");
    Set<Integer> accountIds = reader.readCollection("accountIds", new HashSet<>(), Integer.class);

    // Read them out of order. It still works but logs a warning!
    String surname = reader.readString("surname");
    String name = reader.readString("name");

    List<Address> addresses = reader.readCollection("addresses", new ArrayList<>(), Address.class);

    Integer age = reader.readInt("age");
    User.Gender gender = reader.readEnum("gender", User.Gender.class);
    String notes = reader.readString("notes");

    User user = new User();
    user.setId(id);
    user.setAccountIds(accountIds);
    user.setName(name);
    user.setSurname(surname);
    user.setAge(age);
    user.setGender(gender);
    user.setAddresses(addresses);
    user.setNotes(notes);
    return user;
  }
 @Override
 public void writeTo(ProtoStreamWriter writer, User user) throws IOException {
   writer.writeInt("id", user.getId());
   writer.writeCollection("accountIds", user.getAccountIds(), Integer.class);
   writer.writeString("name", user.getName());
   writer.writeString("surname", user.getSurname());
   writer.writeCollection("addresses", user.getAddresses(), Address.class);
   writer.writeInt("age", user.getAge());
   writer.writeEnum("gender", user.getGender(), User.Gender.class);
   writer.writeString("notes", user.getNotes());
 }
  @Test
  public void testMarshallUser() throws Exception {
    SerializationContext ctx = createContext();

    User user = new User();
    user.setId(1);
    user.setName("John");
    user.setSurname("Batman");
    user.setGender(User.Gender.MALE);
    user.setAccountIds(new HashSet<Integer>(Arrays.asList(1, 3)));
    user.setAddresses(Collections.singletonList(new Address("Old Street", "XYZ42")));

    byte[] bytes = ProtobufUtil.toByteArray(ctx, user);

    User decoded = ProtobufUtil.fromByteArray(ctx, bytes, User.class);

    assertEquals(1, decoded.getId());
    assertEquals("John", decoded.getName());
    assertEquals("Batman", decoded.getSurname());
    assertEquals(User.Gender.MALE, decoded.getGender());

    assertNotNull(decoded.getAddresses());
    assertEquals(1, decoded.getAddresses().size());
    assertEquals("Old Street", decoded.getAddresses().get(0).getStreet());
    assertEquals("XYZ42", decoded.getAddresses().get(0).getPostCode());

    assertNotNull(decoded.getAccountIds());
    assertEquals(2, decoded.getAccountIds().size());
    assertTrue(decoded.getAccountIds().contains(1));
    assertTrue(decoded.getAccountIds().contains(3));
  }