/** @throws Exception If failed. */
  public void testMetaData2() throws Exception {
    BinaryObjectBuilder builder = builder("org.test.MetaTest2");

    builder.setField("objectField", "a", Object.class);

    BinaryObject bo = builder.build();

    BinaryType meta = bo.type();

    assertEquals(expectedTypeName("org.test.MetaTest2"), meta.typeName());
    assertEquals("Object", meta.fieldTypeName("objectField"));
  }
  /** @throws Exception If failed. */
  public void testMetaData() throws Exception {
    BinaryObjectBuilder builder = builder("org.test.MetaTest");

    builder.hashCode(100);

    builder.setField("intField", 1);
    builder.setField("byteArrayField", new byte[] {1, 2, 3});

    BinaryObject po = builder.build();

    BinaryType meta = po.type();

    assertEquals(expectedTypeName("org.test.MetaTest"), meta.typeName());

    Collection<String> fields = meta.fieldNames();

    assertEquals(2, fields.size());

    assertTrue(fields.contains("intField"));
    assertTrue(fields.contains("byteArrayField"));

    assertEquals("int", meta.fieldTypeName("intField"));
    assertEquals("byte[]", meta.fieldTypeName("byteArrayField"));

    builder = builder("org.test.MetaTest");

    builder.hashCode(100);

    builder.setField("intField", 2);
    builder.setField("uuidField", UUID.randomUUID());

    po = builder.build();

    meta = po.type();

    assertEquals(expectedTypeName("org.test.MetaTest"), meta.typeName());

    fields = meta.fieldNames();

    assertEquals(3, fields.size());

    assertTrue(fields.contains("intField"));
    assertTrue(fields.contains("byteArrayField"));
    assertTrue(fields.contains("uuidField"));

    assertEquals("int", meta.fieldTypeName("intField"));
    assertEquals("byte[]", meta.fieldTypeName("byteArrayField"));
    assertEquals("UUID", meta.fieldTypeName("uuidField"));
  }
  /**
   * @param po Portable object.
   * @return Affinity key.
   */
  public Object affinityKey(BinaryObject po) {
    try {
      BinaryType meta = po.type();

      if (meta != null) {
        String affKeyFieldName = meta.affinityKeyFieldName();

        if (affKeyFieldName != null) return po.field(affKeyFieldName);
      } else if (po instanceof BinaryObjectEx) {
        int id = ((BinaryObjectEx) po).typeId();

        String affKeyFieldName = portableCtx.affinityKeyFieldName(id);

        if (affKeyFieldName != null) return po.field(affKeyFieldName);
      }
    } catch (BinaryObjectException e) {
      U.error(log, "Failed to get affinity field from portable object: " + po, e);
    }

    return po;
  }
  /** {@inheritDoc} */
  @Override
  public void addMeta(final int typeId, final BinaryType newMeta) throws BinaryObjectException {
    assert newMeta != null;
    assert newMeta instanceof BinaryTypeImpl;

    BinaryMetadata newMeta0 = ((BinaryTypeImpl) newMeta).metadata();

    final PortableMetadataKey key = new PortableMetadataKey(typeId);

    try {
      BinaryMetadata oldMeta = metaDataCache.localPeek(key);
      BinaryMetadata mergedMeta = PortableUtils.mergeMetadata(oldMeta, newMeta0);

      BinaryObjectException err = metaDataCache.invoke(key, new MetadataProcessor(mergedMeta));

      if (err != null) throw err;
    } catch (CacheException e) {
      throw new BinaryObjectException(
          "Failed to update meta data for type: " + newMeta.typeName(), e);
    }
  }