private void handleNewMembership(String path, SqlSession sql, JsonParser input)
     throws IOException, EngineException {
   JsonUtils.nextExpect(input, "entity");
   long entityId = input.getLongValue();
   JsonUtils.nextExpect(input, "groupId");
   input.getLongValue(); // we ignore this
   JsonUtils.nextExpect(input, "contents");
   byte[] contents = input.getBinaryValue();
   GroupMembership parsed = groupMembershipSerializer.fromJson(contents, entityId, path);
   dbGroups.addMemberFromParent(
       path,
       new EntityParam(entityId),
       parsed.getRemoteIdp(),
       parsed.getTranslationProfile(),
       parsed.getCreationTs(),
       sql);
   JsonUtils.nextExpect(input, JsonToken.END_OBJECT);
 }
  public void deserialize(SqlSession sql, JsonParser input) throws IOException, EngineException {
    JsonUtils.expect(input, JsonToken.START_ARRAY);

    while (input.nextToken() == JsonToken.START_OBJECT) {
      JsonUtils.nextExpect(input, "groupPath");
      String path = input.getText();

      JsonUtils.nextExpect(input, "members");
      JsonUtils.expect(input, JsonToken.START_ARRAY);

      JsonToken element;
      while ((element = input.nextToken()) != null) {
        if (element.isNumeric()) handleLegacyMembership(path, sql, input);
        else if (element.isStructStart()) handleNewMembership(path, sql, input);
        else break;
      }
      JsonUtils.expect(input, JsonToken.END_ARRAY);
      JsonUtils.nextExpect(input, JsonToken.END_OBJECT);
    }
    JsonUtils.expect(input, JsonToken.END_ARRAY);
  }