@Nullable
    @SuppressWarnings("checkstyle:returncount")
    static Metadata resolve(InternalSerializationService ss, Object target, boolean key) {
        try {
            if (target instanceof Data) {
                Data data = (Data) target;
                if (data.isPortable()) {
                    ClassDefinition classDefinition = ss.getPortableContext().lookupClassDefinition(data);
                    return resolvePortable(classDefinition, key);
                } else if (data.isCompact()) {
                    return resolveCompact(ss.extractSchemaFromData(data), key);
                } else if (data.isJson()) {
                    return null;
                } else {
                    return resolveJava(ss.toObject(data).getClass(), key);
                }
            } else if (target instanceof VersionedPortable) {
                VersionedPortable portable = (VersionedPortable) target;
                ClassDefinition classDefinition = ss.getPortableContext()
                        .lookupClassDefinition(portable.getFactoryId(), portable.getClassId(), portable.getClassVersion());
                return resolvePortable(classDefinition, key);
            } else if (target instanceof Portable) {
                Portable portable = (Portable) target;
                ClassDefinition classDefinition = ss.getPortableContext()
                        .lookupClassDefinition(portable.getFactoryId(), portable.getClassId(), 0);
                return resolvePortable(classDefinition, key);
            } else if (target instanceof PortableGenericRecord) {
                return resolvePortable(((PortableGenericRecord) target).getClassDefinition(), key);
            } else if (target instanceof CompactGenericRecord) {
                return resolveCompact(((CompactGenericRecord) target).getSchema(), key);
            } else if (ss.isCompactSerializable(target)) {
                Schema schema = ss.extractSchemaFromObject(target);
                return resolveCompact(schema, key);
            } else if (target instanceof HazelcastJsonValue) {
                return null;
            } else {
                return resolveJava(target.getClass(), key);
            }
        } catch (Exception e) {
            return null;
        }
    }
@Test
    public void test_versionedPortable() {
        ClassDefinition classDefinition = new ClassDefinitionBuilder(PORTABLE_FACTORY_ID, PORTABLE_CLASS_ID, PORTABLE_CLASS_VERSION).build();
        InternalSerializationService ss = new DefaultSerializationServiceBuilder().addClassDefinition(classDefinition).build();

        Metadata metadata = SampleMetadataResolver.resolve(ss, new VersionedPortableClass(), key);
        assertThat(metadata.options()).containsExactly(
                entry(key ? OPTION_KEY_FORMAT : OPTION_VALUE_FORMAT, PORTABLE_FORMAT),
                entry(key ? OPTION_KEY_FACTORY_ID : OPTION_VALUE_FACTORY_ID, String.valueOf(PORTABLE_FACTORY_ID)),
                entry(key ? OPTION_KEY_CLASS_ID : OPTION_VALUE_CLASS_ID, String.valueOf(PORTABLE_CLASS_ID)),
                entry(key ? OPTION_KEY_CLASS_VERSION : OPTION_VALUE_CLASS_VERSION, String.valueOf(PORTABLE_CLASS_VERSION))
        );

        metadata = SampleMetadataResolver.resolve(ss, ss.toData(new VersionedPortableClass()), key);
        assertThat(metadata.options()).containsExactly(
                entry(key ? OPTION_KEY_FORMAT : OPTION_VALUE_FORMAT, PORTABLE_FORMAT),
                entry(key ? OPTION_KEY_FACTORY_ID : OPTION_VALUE_FACTORY_ID, String.valueOf(PORTABLE_FACTORY_ID)),
                entry(key ? OPTION_KEY_CLASS_ID : OPTION_VALUE_CLASS_ID, String.valueOf(PORTABLE_CLASS_ID)),
                entry(key ? OPTION_KEY_CLASS_VERSION : OPTION_VALUE_CLASS_VERSION, String.valueOf(PORTABLE_CLASS_VERSION))
        );
    }