You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/12/11 10:38:22 UTC

[19/31] ignite git commit: ignite-2065: rename "portable" packages to "binary"

http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
deleted file mode 100644
index 9a65da1..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.math.BigDecimal;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.UUID;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.binary.BinaryIdMapper;
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinarySerializer;
-import org.apache.ignite.binary.Binarylizable;
-import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
-import org.jetbrains.annotations.Nullable;
-import sun.misc.Unsafe;
-
-import static java.lang.reflect.Modifier.isStatic;
-import static java.lang.reflect.Modifier.isTransient;
-
-/**
- * Portable class descriptor.
- */
-public class PortableClassDescriptor {
-    /** */
-    public static final Unsafe UNSAFE = GridUnsafe.unsafe();
-
-    /** */
-    private final PortableContext ctx;
-
-    /** */
-    private final Class<?> cls;
-
-    /** */
-    private final BinarySerializer serializer;
-
-    /** ID mapper. */
-    private final BinaryIdMapper idMapper;
-
-    /** */
-    private final BinaryWriteMode mode;
-
-    /** */
-    private final boolean userType;
-
-    /** */
-    private final int typeId;
-
-    /** */
-    private final String typeName;
-
-    /** Affinity key field name. */
-    private final String affKeyFieldName;
-
-    /** */
-    private final Constructor<?> ctor;
-
-    /** */
-    private final BinaryFieldAccessor[] fields;
-
-    /** */
-    private final Method writeReplaceMtd;
-
-    /** */
-    private final Method readResolveMtd;
-
-    /** */
-    private final Map<String, Integer> stableFieldsMeta;
-
-    /** Object schemas. Initialized only for serializable classes and contains only 1 entry. */
-    private final PortableSchema stableSchema;
-
-    /** Schema registry. */
-    private final PortableSchemaRegistry schemaReg;
-
-    /** */
-    private final boolean registered;
-
-    /** */
-    private final boolean useOptMarshaller;
-
-    /** */
-    private final boolean excluded;
-
-    /**
-     * @param ctx Context.
-     * @param cls Class.
-     * @param userType User type flag.
-     * @param typeId Type ID.
-     * @param typeName Type name.
-     * @param affKeyFieldName Affinity key field name.
-     * @param idMapper ID mapper.
-     * @param serializer Serializer.
-     * @param metaDataEnabled Metadata enabled flag.
-     * @param registered Whether typeId has been successfully registered by MarshallerContext or not.
-     * @param predefined Whether the class is predefined or not.
-     * @throws BinaryObjectException In case of error.
-     */
-    PortableClassDescriptor(
-        PortableContext ctx,
-        Class<?> cls,
-        boolean userType,
-        int typeId,
-        String typeName,
-        @Nullable String affKeyFieldName,
-        @Nullable BinaryIdMapper idMapper,
-        @Nullable BinarySerializer serializer,
-        boolean metaDataEnabled,
-        boolean registered,
-        boolean predefined
-    ) throws BinaryObjectException {
-        assert ctx != null;
-        assert cls != null;
-        assert idMapper != null;
-
-        this.ctx = ctx;
-        this.cls = cls;
-        this.typeId = typeId;
-        this.userType = userType;
-        this.typeName = typeName;
-        this.affKeyFieldName = affKeyFieldName;
-        this.serializer = serializer;
-        this.idMapper = idMapper;
-        this.registered = registered;
-
-        schemaReg = ctx.schemaRegistry(typeId);
-
-        excluded = MarshallerExclusions.isExcluded(cls);
-
-        useOptMarshaller = !predefined && initUseOptimizedMarshallerFlag();
-
-        if (excluded)
-            mode = BinaryWriteMode.EXCLUSION;
-        else {
-            if (cls == BinaryEnumObjectImpl.class)
-                mode = BinaryWriteMode.PORTABLE_ENUM;
-            else
-                mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls);
-        }
-
-        switch (mode) {
-            case P_BYTE:
-            case P_BOOLEAN:
-            case P_SHORT:
-            case P_CHAR:
-            case P_INT:
-            case P_LONG:
-            case P_FLOAT:
-            case P_DOUBLE:
-            case BYTE:
-            case SHORT:
-            case INT:
-            case LONG:
-            case FLOAT:
-            case DOUBLE:
-            case CHAR:
-            case BOOLEAN:
-            case DECIMAL:
-            case STRING:
-            case UUID:
-            case DATE:
-            case TIMESTAMP:
-            case BYTE_ARR:
-            case SHORT_ARR:
-            case INT_ARR:
-            case LONG_ARR:
-            case FLOAT_ARR:
-            case DOUBLE_ARR:
-            case CHAR_ARR:
-            case BOOLEAN_ARR:
-            case DECIMAL_ARR:
-            case STRING_ARR:
-            case UUID_ARR:
-            case DATE_ARR:
-            case TIMESTAMP_ARR:
-            case OBJECT_ARR:
-            case COL:
-            case MAP:
-            case PORTABLE_OBJ:
-            case ENUM:
-            case PORTABLE_ENUM:
-            case ENUM_ARR:
-            case CLASS:
-            case EXCLUSION:
-                ctor = null;
-                fields = null;
-                stableFieldsMeta = null;
-                stableSchema = null;
-
-                break;
-
-            case PORTABLE:
-            case EXTERNALIZABLE:
-                ctor = constructor(cls);
-                fields = null;
-                stableFieldsMeta = null;
-                stableSchema = null;
-
-                break;
-
-            case OBJECT:
-                // Must not use constructor to honor transient fields semantics.
-                ctor = null;
-                ArrayList<BinaryFieldAccessor> fields0 = new ArrayList<>();
-                stableFieldsMeta = metaDataEnabled ? new HashMap<String, Integer>() : null;
-
-                PortableSchema.Builder schemaBuilder = PortableSchema.Builder.newBuilder();
-
-                Collection<String> names = new HashSet<>();
-                Collection<Integer> ids = new HashSet<>();
-
-                for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
-                    for (Field f : c.getDeclaredFields()) {
-                        int mod = f.getModifiers();
-
-                        if (!isStatic(mod) && !isTransient(mod)) {
-                            f.setAccessible(true);
-
-                            String name = f.getName();
-
-                            if (!names.add(name))
-                                throw new BinaryObjectException("Duplicate field name [fieldName=" + name +
-                                    ", cls=" + cls.getName() + ']');
-
-                            int fieldId = idMapper.fieldId(typeId, name);
-
-                            if (!ids.add(fieldId))
-                                throw new BinaryObjectException("Duplicate field ID: " + name);
-
-                            BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId);
-
-                            fields0.add(fieldInfo);
-
-                            schemaBuilder.addField(fieldId);
-
-                            if (metaDataEnabled)
-                                stableFieldsMeta.put(name, fieldInfo.mode().typeId());
-                        }
-                    }
-                }
-
-                fields = fields0.toArray(new BinaryFieldAccessor[fields0.size()]);
-
-                stableSchema = schemaBuilder.build();
-
-                break;
-
-            default:
-                // Should never happen.
-                throw new BinaryObjectException("Invalid mode: " + mode);
-        }
-
-        if (mode == BinaryWriteMode.PORTABLE || mode == BinaryWriteMode.EXTERNALIZABLE ||
-            mode == BinaryWriteMode.OBJECT) {
-            readResolveMtd = U.findNonPublicMethod(cls, "readResolve");
-            writeReplaceMtd = U.findNonPublicMethod(cls, "writeReplace");
-        }
-        else {
-            readResolveMtd = null;
-            writeReplaceMtd = null;
-        }
-    }
-
-    /**
-     * @return {@code True} if enum.
-     */
-    boolean isEnum() {
-        return mode == BinaryWriteMode.ENUM;
-    }
-
-    /**
-     * @return Described class.
-     */
-    Class<?> describedClass() {
-        return cls;
-    }
-
-    /**
-     * @return Type ID.
-     */
-    public int typeId() {
-        return typeId;
-    }
-
-    /**
-     * @return User type flag.
-     */
-    public boolean userType() {
-        return userType;
-    }
-
-    /**
-     * @return Fields meta data.
-     */
-    Map<String, Integer> fieldsMeta() {
-        return stableFieldsMeta;
-    }
-
-    /**
-     * @return Schema.
-     */
-    PortableSchema schema() {
-        return stableSchema;
-    }
-
-    /**
-     * @return Whether typeId has been successfully registered by MarshallerContext or not.
-     */
-    public boolean registered() {
-        return registered;
-    }
-
-    /**
-     * @return {@code true} if {@link OptimizedMarshaller} must be used instead of {@link BinaryMarshaller}
-     * for object serialization and deserialization.
-     */
-    public boolean useOptimizedMarshaller() {
-        return useOptMarshaller;
-    }
-
-    /**
-     * Checks whether the class values are explicitly excluded from marshalling.
-     *
-     * @return {@code true} if excluded, {@code false} otherwise.
-     */
-    public boolean excluded() {
-        return excluded;
-    }
-
-    /**
-     * @return portableWriteReplace() method
-     */
-    @Nullable Method getWriteReplaceMethod() {
-        return writeReplaceMtd;
-    }
-
-    /**
-     * @return portableReadResolve() method
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    @Nullable Method getReadResolveMethod() {
-        return readResolveMtd;
-    }
-
-    /**
-     * @param obj Object.
-     * @param writer Writer.
-     * @throws BinaryObjectException In case of error.
-     */
-    void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
-        assert obj != null;
-        assert writer != null;
-
-        writer.typeId(typeId);
-
-        switch (mode) {
-            case P_BYTE:
-            case BYTE:
-                writer.writeByteFieldPrimitive((byte) obj);
-
-                break;
-
-            case P_SHORT:
-            case SHORT:
-                writer.writeShortFieldPrimitive((short)obj);
-
-                break;
-
-            case P_INT:
-            case INT:
-                writer.writeIntFieldPrimitive((int) obj);
-
-                break;
-
-            case P_LONG:
-            case LONG:
-                writer.writeLongFieldPrimitive((long) obj);
-
-                break;
-
-            case P_FLOAT:
-            case FLOAT:
-                writer.writeFloatFieldPrimitive((float) obj);
-
-                break;
-
-            case P_DOUBLE:
-            case DOUBLE:
-                writer.writeDoubleFieldPrimitive((double) obj);
-
-                break;
-
-            case P_CHAR:
-            case CHAR:
-                writer.writeCharFieldPrimitive((char) obj);
-
-                break;
-
-            case P_BOOLEAN:
-            case BOOLEAN:
-                writer.writeBooleanFieldPrimitive((boolean) obj);
-
-                break;
-
-            case DECIMAL:
-                writer.doWriteDecimal((BigDecimal)obj);
-
-                break;
-
-            case STRING:
-                writer.doWriteString((String)obj);
-
-                break;
-
-            case UUID:
-                writer.doWriteUuid((UUID)obj);
-
-                break;
-
-            case DATE:
-                writer.doWriteDate((Date)obj);
-
-                break;
-
-            case TIMESTAMP:
-                writer.doWriteTimestamp((Timestamp)obj);
-
-                break;
-
-            case BYTE_ARR:
-                writer.doWriteByteArray((byte[])obj);
-
-                break;
-
-            case SHORT_ARR:
-                writer.doWriteShortArray((short[]) obj);
-
-                break;
-
-            case INT_ARR:
-                writer.doWriteIntArray((int[]) obj);
-
-                break;
-
-            case LONG_ARR:
-                writer.doWriteLongArray((long[]) obj);
-
-                break;
-
-            case FLOAT_ARR:
-                writer.doWriteFloatArray((float[]) obj);
-
-                break;
-
-            case DOUBLE_ARR:
-                writer.doWriteDoubleArray((double[]) obj);
-
-                break;
-
-            case CHAR_ARR:
-                writer.doWriteCharArray((char[]) obj);
-
-                break;
-
-            case BOOLEAN_ARR:
-                writer.doWriteBooleanArray((boolean[]) obj);
-
-                break;
-
-            case DECIMAL_ARR:
-                writer.doWriteDecimalArray((BigDecimal[]) obj);
-
-                break;
-
-            case STRING_ARR:
-                writer.doWriteStringArray((String[]) obj);
-
-                break;
-
-            case UUID_ARR:
-                writer.doWriteUuidArray((UUID[]) obj);
-
-                break;
-
-            case DATE_ARR:
-                writer.doWriteDateArray((Date[]) obj);
-
-                break;
-
-            case TIMESTAMP_ARR:
-                writer.doWriteTimestampArray((Timestamp[]) obj);
-
-                break;
-
-            case OBJECT_ARR:
-                writer.doWriteObjectArray((Object[])obj);
-
-                break;
-
-            case COL:
-                writer.doWriteCollection((Collection<?>)obj);
-
-                break;
-
-            case MAP:
-                writer.doWriteMap((Map<?, ?>)obj);
-
-                break;
-
-            case ENUM:
-                writer.doWriteEnum((Enum<?>)obj);
-
-                break;
-
-            case PORTABLE_ENUM:
-                writer.doWritePortableEnum((BinaryEnumObjectImpl)obj);
-
-                break;
-
-            case ENUM_ARR:
-                writer.doWriteEnumArray((Object[])obj);
-
-                break;
-
-            case CLASS:
-                writer.doWriteClass((Class)obj);
-
-                break;
-
-            case PORTABLE_OBJ:
-                writer.doWritePortableObject((BinaryObjectImpl)obj);
-
-                break;
-
-            case PORTABLE:
-                if (preWrite(writer, obj)) {
-                    try {
-                        if (serializer != null)
-                            serializer.writeBinary(obj, writer);
-                        else
-                            ((Binarylizable)obj).writeBinary(writer);
-
-                        postWrite(writer, obj);
-
-                        // Check whether we need to update metadata.
-                        if (obj.getClass() != BinaryMetadata.class) {
-                            int schemaId = writer.schemaId();
-
-                            if (schemaReg.schema(schemaId) == null) {
-                                // This is new schema, let's update metadata.
-                                BinaryMetadataCollector collector =
-                                    new BinaryMetadataCollector(typeId, typeName, idMapper);
-
-                                if (serializer != null)
-                                    serializer.writeBinary(obj, collector);
-                                else
-                                    ((Binarylizable)obj).writeBinary(collector);
-
-                                PortableSchema newSchema = collector.schema();
-
-                                BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(),
-                                    affKeyFieldName, Collections.singleton(newSchema), false);
-
-                                ctx.updateMetadata(typeId, meta);
-
-                                schemaReg.addSchema(newSchema.schemaId(), newSchema);
-                            }
-                        }
-                    }
-                    finally {
-                        writer.popSchema();
-                    }
-                }
-
-                break;
-
-            case EXTERNALIZABLE:
-                if (preWrite(writer, obj)) {
-                    writer.rawWriter();
-
-                    try {
-                        ((Externalizable)obj).writeExternal(writer);
-
-                        postWrite(writer, obj);
-                    }
-                    catch (IOException e) {
-                        throw new BinaryObjectException("Failed to write Externalizable object: " + obj, e);
-                    }
-                    finally {
-                        writer.popSchema();
-                    }
-                }
-
-                break;
-
-            case OBJECT:
-                if (preWrite(writer, obj)) {
-                    try {
-                        for (BinaryFieldAccessor info : fields)
-                            info.write(obj, writer);
-
-                        writer.schemaId(stableSchema.schemaId());
-
-                        postWrite(writer, obj);
-                    }
-                    finally {
-                        writer.popSchema();
-                    }
-                }
-
-                break;
-
-            default:
-                assert false : "Invalid mode: " + mode;
-        }
-    }
-
-    /**
-     * @param reader Reader.
-     * @return Object.
-     * @throws BinaryObjectException If failed.
-     */
-    Object read(BinaryReaderExImpl reader) throws BinaryObjectException {
-        assert reader != null;
-
-        Object res;
-
-        switch (mode) {
-            case PORTABLE:
-                res = newInstance();
-
-                reader.setHandle(res);
-
-                if (serializer != null)
-                    serializer.readBinary(res, reader);
-                else
-                    ((Binarylizable)res).readBinary(reader);
-
-                break;
-
-            case EXTERNALIZABLE:
-                res = newInstance();
-
-                reader.setHandle(res);
-
-                try {
-                    ((Externalizable)res).readExternal(reader);
-                }
-                catch (IOException | ClassNotFoundException e) {
-                    throw new BinaryObjectException("Failed to read Externalizable object: " +
-                        res.getClass().getName(), e);
-                }
-
-                break;
-
-            case OBJECT:
-                res = newInstance();
-
-                reader.setHandle(res);
-
-                for (BinaryFieldAccessor info : fields)
-                    info.read(res, reader);
-
-                break;
-
-            default:
-                assert false : "Invalid mode: " + mode;
-
-                return null;
-        }
-
-        if (readResolveMtd != null) {
-            try {
-                res = readResolveMtd.invoke(res);
-
-                reader.setHandle(res);
-            }
-            catch (IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-            catch (InvocationTargetException e) {
-                if (e.getTargetException() instanceof BinaryObjectException)
-                    throw (BinaryObjectException)e.getTargetException();
-
-                throw new BinaryObjectException("Failed to execute readResolve() method on " + res, e);
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Pre-write phase.
-     *
-     * @param writer Writer.
-     * @param obj Object.
-     * @return Whether further write is needed.
-     */
-    private boolean preWrite(BinaryWriterExImpl writer, Object obj) {
-        if (writer.tryWriteAsHandle(obj))
-            return false;
-
-        writer.preWrite(registered ? null : cls.getName());
-
-        return true;
-    }
-
-    /**
-     * Post-write phase.
-     *
-     * @param writer Writer.
-     * @param obj Object.
-     */
-    private void postWrite(BinaryWriterExImpl writer, Object obj) {
-        writer.postWrite(userType, registered, obj instanceof CacheObjectImpl ? 0 : obj.hashCode());
-    }
-
-    /**
-     * @return Instance.
-     * @throws BinaryObjectException In case of error.
-     */
-    private Object newInstance() throws BinaryObjectException {
-        try {
-            return ctor != null ? ctor.newInstance() : UNSAFE.allocateInstance(cls);
-        }
-        catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
-            throw new BinaryObjectException("Failed to instantiate instance: " + cls, e);
-        }
-    }
-
-    /**
-     * @param cls Class.
-     * @return Constructor.
-     * @throws BinaryObjectException If constructor doesn't exist.
-     */
-    @SuppressWarnings("ConstantConditions")
-    @Nullable private static Constructor<?> constructor(Class<?> cls) throws BinaryObjectException {
-        assert cls != null;
-
-        try {
-            Constructor<?> ctor = U.forceEmptyConstructor(cls);
-
-            if (ctor == null)
-                throw new BinaryObjectException("Failed to find empty constructor for class: " + cls.getName());
-
-            ctor.setAccessible(true);
-
-            return ctor;
-        }
-        catch (IgniteCheckedException e) {
-            throw new BinaryObjectException("Failed to get constructor for class: " + cls.getName(), e);
-        }
-    }
-
-    /**
-     * Determines whether to use {@link OptimizedMarshaller} for serialization or
-     * not.
-     *
-     * @return {@code true} if to use, {@code false} otherwise.
-     */
-    @SuppressWarnings("unchecked")
-    private boolean initUseOptimizedMarshallerFlag() {
-        for (Class c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
-            try {
-                Method writeObj = c.getDeclaredMethod("writeObject", ObjectOutputStream.class);
-                Method readObj = c.getDeclaredMethod("readObject", ObjectInputStream.class);
-
-                if (!Modifier.isStatic(writeObj.getModifiers()) && !Modifier.isStatic(readObj.getModifiers()) &&
-                    writeObj.getReturnType() == void.class && readObj.getReturnType() == void.class)
-                    return true;
-            }
-            catch (NoSuchMethodException ignored) {
-                // No-op.
-            }
-        }
-
-        return false;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
deleted file mode 100644
index f02867b..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.binary.BinaryIdMapper;
-import org.apache.ignite.binary.BinaryInvalidTypeException;
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinarySerializer;
-import org.apache.ignite.binary.BinaryType;
-import org.apache.ignite.binary.BinaryTypeConfiguration;
-import org.apache.ignite.cache.CacheKeyConfiguration;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteKernal;
-import org.apache.ignite.internal.IgnitionEx;
-import org.apache.ignite.internal.processors.cache.portable.CacheObjectBinaryProcessorImpl;
-import org.apache.ignite.internal.processors.datastructures.CollocatedQueueItemKey;
-import org.apache.ignite.internal.processors.datastructures.CollocatedSetItemKey;
-import org.apache.ignite.internal.util.IgniteUtils;
-import org.apache.ignite.internal.util.lang.GridMapEntry;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.marshaller.MarshallerContext;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
-import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
-
-import java.io.Externalizable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * Portable context.
- */
-public class PortableContext implements Externalizable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** */
-    private static final ClassLoader dfltLdr = U.gridClassLoader();
-
-    /** */
-    private final ConcurrentMap<Class<?>, PortableClassDescriptor> descByCls = new ConcurrentHashMap8<>();
-
-    /** Holds classes loaded by default class loader only. */
-    private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>();
-
-    /** */
-    private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>();
-
-    /** */
-    private final Map<String, Integer> predefinedTypeNames = new HashMap<>();
-
-    /** */
-    private final Map<Class<? extends Collection>, Byte> colTypes = new HashMap<>();
-
-    /** */
-    private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>();
-
-    /** */
-    private final ConcurrentMap<Integer, BinaryIdMapper> mappers = new ConcurrentHashMap8<>(0);
-
-    /** Affinity key field names. */
-    private final ConcurrentMap<Integer, String> affKeyFieldNames = new ConcurrentHashMap8<>(0);
-
-    /** */
-    private final Map<String, BinaryIdMapper> typeMappers = new ConcurrentHashMap8<>(0);
-
-    /** */
-    private BinaryMetadataHandler metaHnd;
-
-    /** Actual marshaller. */
-    private BinaryMarshaller marsh;
-
-    /** */
-    private MarshallerContext marshCtx;
-
-    /** */
-    private String gridName;
-
-    /** */
-    private IgniteConfiguration igniteCfg;
-
-    /** */
-    private final OptimizedMarshaller optmMarsh = new OptimizedMarshaller();
-
-    /** Compact footer flag. */
-    private boolean compactFooter;
-
-    /** Object schemas. */
-    private volatile Map<Integer, PortableSchemaRegistry> schemas;
-
-    /**
-     * For {@link Externalizable}.
-     */
-    public PortableContext() {
-        // No-op.
-    }
-
-    /**
-     * @param metaHnd Meta data handler.
-     * @param igniteCfg Ignite configuration.
-     */
-    public PortableContext(BinaryMetadataHandler metaHnd, IgniteConfiguration igniteCfg) {
-        assert metaHnd != null;
-        assert igniteCfg != null;
-
-        this.metaHnd = metaHnd;
-        this.igniteCfg = igniteCfg;
-
-        gridName = igniteCfg.getGridName();
-
-        colTypes.put(ArrayList.class, GridPortableMarshaller.ARR_LIST);
-        colTypes.put(LinkedList.class, GridPortableMarshaller.LINKED_LIST);
-        colTypes.put(HashSet.class, GridPortableMarshaller.HASH_SET);
-        colTypes.put(LinkedHashSet.class, GridPortableMarshaller.LINKED_HASH_SET);
-
-        mapTypes.put(HashMap.class, GridPortableMarshaller.HASH_MAP);
-        mapTypes.put(LinkedHashMap.class, GridPortableMarshaller.LINKED_HASH_MAP);
-
-        // IDs range from [0..200] is used by Java SDK API and GridGain legacy API
-
-        registerPredefinedType(Byte.class, GridPortableMarshaller.BYTE);
-        registerPredefinedType(Boolean.class, GridPortableMarshaller.BOOLEAN);
-        registerPredefinedType(Short.class, GridPortableMarshaller.SHORT);
-        registerPredefinedType(Character.class, GridPortableMarshaller.CHAR);
-        registerPredefinedType(Integer.class, GridPortableMarshaller.INT);
-        registerPredefinedType(Long.class, GridPortableMarshaller.LONG);
-        registerPredefinedType(Float.class, GridPortableMarshaller.FLOAT);
-        registerPredefinedType(Double.class, GridPortableMarshaller.DOUBLE);
-        registerPredefinedType(String.class, GridPortableMarshaller.STRING);
-        registerPredefinedType(BigDecimal.class, GridPortableMarshaller.DECIMAL);
-        registerPredefinedType(Date.class, GridPortableMarshaller.DATE);
-        registerPredefinedType(Timestamp.class, GridPortableMarshaller.TIMESTAMP);
-        registerPredefinedType(UUID.class, GridPortableMarshaller.UUID);
-
-        registerPredefinedType(byte[].class, GridPortableMarshaller.BYTE_ARR);
-        registerPredefinedType(short[].class, GridPortableMarshaller.SHORT_ARR);
-        registerPredefinedType(int[].class, GridPortableMarshaller.INT_ARR);
-        registerPredefinedType(long[].class, GridPortableMarshaller.LONG_ARR);
-        registerPredefinedType(float[].class, GridPortableMarshaller.FLOAT_ARR);
-        registerPredefinedType(double[].class, GridPortableMarshaller.DOUBLE_ARR);
-        registerPredefinedType(char[].class, GridPortableMarshaller.CHAR_ARR);
-        registerPredefinedType(boolean[].class, GridPortableMarshaller.BOOLEAN_ARR);
-        registerPredefinedType(BigDecimal[].class, GridPortableMarshaller.DECIMAL_ARR);
-        registerPredefinedType(String[].class, GridPortableMarshaller.STRING_ARR);
-        registerPredefinedType(UUID[].class, GridPortableMarshaller.UUID_ARR);
-        registerPredefinedType(Date[].class, GridPortableMarshaller.DATE_ARR);
-        registerPredefinedType(Timestamp[].class, GridPortableMarshaller.TIMESTAMP_ARR);
-        registerPredefinedType(Object[].class, GridPortableMarshaller.OBJ_ARR);
-
-        registerPredefinedType(ArrayList.class, 0);
-        registerPredefinedType(LinkedList.class, 0);
-        registerPredefinedType(HashSet.class, 0);
-        registerPredefinedType(LinkedHashSet.class, 0);
-
-        registerPredefinedType(HashMap.class, 0);
-        registerPredefinedType(LinkedHashMap.class, 0);
-
-        registerPredefinedType(GridMapEntry.class, 60);
-        registerPredefinedType(IgniteBiTuple.class, 61);
-        registerPredefinedType(T2.class, 62);
-
-        // IDs range [200..1000] is used by Ignite internal APIs.
-    }
-
-    /**
-     * @return Marshaller.
-     */
-    public BinaryMarshaller marshaller() {
-        return marsh;
-    }
-
-    /**
-     * @return Ignite configuration.
-     */
-    public IgniteConfiguration configuration(){
-        return igniteCfg;
-    }
-
-    /**
-     * @param marsh Portable marshaller.
-     * @param cfg Configuration.
-     * @throws BinaryObjectException In case of error.
-     */
-    public void configure(BinaryMarshaller marsh, IgniteConfiguration cfg) throws BinaryObjectException {
-        if (marsh == null)
-            return;
-
-        this.marsh = marsh;
-
-        marshCtx = marsh.getContext();
-
-        BinaryConfiguration binaryCfg = cfg.getBinaryConfiguration();
-
-        if (binaryCfg == null)
-            binaryCfg = new BinaryConfiguration();
-
-        assert marshCtx != null;
-
-        optmMarsh.setContext(marshCtx);
-
-        configure(
-            binaryCfg.getIdMapper(),
-            binaryCfg.getSerializer(),
-            binaryCfg.getTypeConfigurations()
-        );
-
-        compactFooter = binaryCfg.isCompactFooter();
-    }
-
-    /**
-     * @param globalIdMapper ID mapper.
-     * @param globalSerializer Serializer.
-     * @param typeCfgs Type configurations.
-     * @throws BinaryObjectException In case of error.
-     */
-    private void configure(
-        BinaryIdMapper globalIdMapper,
-        BinarySerializer globalSerializer,
-        Collection<BinaryTypeConfiguration> typeCfgs
-    ) throws BinaryObjectException {
-        TypeDescriptors descs = new TypeDescriptors();
-
-        Map<String, String> affFields = new HashMap<>();
-
-        if (!F.isEmpty(igniteCfg.getCacheKeyConfiguration())) {
-            for (CacheKeyConfiguration keyCfg : igniteCfg.getCacheKeyConfiguration())
-                affFields.put(keyCfg.getTypeName(), keyCfg.getAffinityKeyFieldName());
-        }
-
-        if (typeCfgs != null) {
-            for (BinaryTypeConfiguration typeCfg : typeCfgs) {
-                String clsName = typeCfg.getTypeName();
-
-                if (clsName == null)
-                    throw new BinaryObjectException("Class name is required for portable type configuration.");
-
-                BinaryIdMapper idMapper = globalIdMapper;
-
-                if (typeCfg.getIdMapper() != null)
-                    idMapper = typeCfg.getIdMapper();
-
-                idMapper = BinaryInternalIdMapper.create(idMapper);
-
-                BinarySerializer serializer = globalSerializer;
-
-                if (typeCfg.getSerializer() != null)
-                    serializer = typeCfg.getSerializer();
-
-                if (clsName.endsWith(".*")) {
-                    String pkgName = clsName.substring(0, clsName.length() - 2);
-
-                    for (String clsName0 : classesInPackage(pkgName))
-                        descs.add(clsName0, idMapper, serializer, affFields.get(clsName0),
-                            typeCfg.isEnum(), true);
-                }
-                else
-                    descs.add(clsName, idMapper, serializer, affFields.get(clsName),
-                        typeCfg.isEnum(), false);
-            }
-        }
-
-        for (TypeDescriptor desc : descs.descriptors())
-            registerUserType(desc.clsName, desc.idMapper, desc.serializer, desc.affKeyFieldName, desc.isEnum);
-
-        BinaryInternalIdMapper dfltMapper = BinaryInternalIdMapper.create(globalIdMapper);
-
-        // Put affinity field names for unconfigured types.
-        for (Map.Entry<String, String> entry : affFields.entrySet()) {
-            String typeName = entry.getKey();
-
-            int typeId = dfltMapper.typeId(typeName);
-
-            affKeyFieldNames.putIfAbsent(typeId, entry.getValue());
-        }
-
-        addSystemClassAffinityKey(CollocatedSetItemKey.class);
-        addSystemClassAffinityKey(CollocatedQueueItemKey.class);
-    }
-
-    /**
-     * @param cls Class.
-     */
-    private void addSystemClassAffinityKey(Class<?> cls) {
-        String fieldName = affinityFieldName(cls);
-
-        assert fieldName != null : cls;
-
-        affKeyFieldNames.putIfAbsent(cls.getName().hashCode(), affinityFieldName(cls));
-    }
-
-    /**
-     * @param pkgName Package name.
-     * @return Class names.
-     */
-    @SuppressWarnings("ConstantConditions")
-    private static Iterable<String> classesInPackage(String pkgName) {
-        assert pkgName != null;
-
-        Collection<String> clsNames = new ArrayList<>();
-
-        ClassLoader ldr = U.gridClassLoader();
-
-        if (ldr instanceof URLClassLoader) {
-            String pkgPath = pkgName.replaceAll("\\.", "/");
-
-            URL[] urls = ((URLClassLoader)ldr).getURLs();
-
-            for (URL url : urls) {
-                String proto = url.getProtocol().toLowerCase();
-
-                if ("file".equals(proto)) {
-                    try {
-                        File cpElement = new File(url.toURI());
-
-                        if (cpElement.isDirectory()) {
-                            File pkgDir = new File(cpElement, pkgPath);
-
-                            if (pkgDir.isDirectory()) {
-                                for (File file : pkgDir.listFiles()) {
-                                    String fileName = file.getName();
-
-                                    if (file.isFile() && fileName.toLowerCase().endsWith(".class"))
-                                        clsNames.add(pkgName + '.' + fileName.substring(0, fileName.length() - 6));
-                                }
-                            }
-                        }
-                        else if (cpElement.isFile()) {
-                            try {
-                                JarFile jar = new JarFile(cpElement);
-
-                                Enumeration<JarEntry> entries = jar.entries();
-
-                                while (entries.hasMoreElements()) {
-                                    String entry = entries.nextElement().getName();
-
-                                    if (entry.startsWith(pkgPath) && entry.endsWith(".class")) {
-                                        String clsName = entry.substring(pkgPath.length() + 1, entry.length() - 6);
-
-                                        if (!clsName.contains("/") && !clsName.contains("\\"))
-                                            clsNames.add(pkgName + '.' + clsName);
-                                    }
-                                }
-                            }
-                            catch (IOException ignored) {
-                                // No-op.
-                            }
-                        }
-                    }
-                    catch (URISyntaxException ignored) {
-                        // No-op.
-                    }
-                }
-            }
-        }
-
-        return clsNames;
-    }
-
-    /**
-     * @param cls Class.
-     * @return Class descriptor.
-     * @throws BinaryObjectException In case of error.
-     */
-    public PortableClassDescriptor descriptorForClass(Class<?> cls, boolean deserialize)
-        throws BinaryObjectException {
-        assert cls != null;
-
-        PortableClassDescriptor desc = descByCls.get(cls);
-
-        if (desc == null || !desc.registered())
-            desc = registerClassDescriptor(cls, deserialize);
-
-        return desc;
-    }
-
-    /**
-     * @param userType User type or not.
-     * @param typeId Type ID.
-     * @param ldr Class loader.
-     * @return Class descriptor.
-     */
-    public PortableClassDescriptor descriptorForTypeId(
-        boolean userType,
-        int typeId,
-        ClassLoader ldr,
-        boolean deserialize
-    ) {
-        assert typeId != GridPortableMarshaller.UNREGISTERED_TYPE_ID;
-
-        //TODO: As a workaround for IGNITE-1358 we always check the predefined map before without checking 'userType'
-        PortableClassDescriptor desc = predefinedTypes.get(typeId);
-
-        if (desc != null)
-            return desc;
-
-        if (ldr == null)
-            ldr = dfltLdr;
-
-        // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here
-        // giving a chance to a custom class loader to reload type's class.
-        if (userType && ldr.equals(dfltLdr)) {
-            desc = userTypes.get(typeId);
-
-            if (desc != null)
-                return desc;
-        }
-
-        Class cls;
-
-        try {
-            cls = marshCtx.getClass(typeId, ldr);
-
-            desc = descByCls.get(cls);
-        }
-        catch (ClassNotFoundException e) {
-            // Class might have been loaded by default class loader.
-            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
-                return desc;
-
-            throw new BinaryInvalidTypeException(e);
-        }
-        catch (IgniteCheckedException e) {
-            // Class might have been loaded by default class loader.
-            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
-                return desc;
-
-            throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e);
-        }
-
-        if (desc == null) {
-            desc = registerClassDescriptor(cls, deserialize);
-
-            assert desc.typeId() == typeId;
-        }
-
-        return desc;
-    }
-
-    /**
-     * Creates and registers {@link PortableClassDescriptor} for the given {@code class}.
-     *
-     * @param cls Class.
-     * @return Class descriptor.
-     */
-    private PortableClassDescriptor registerClassDescriptor(Class<?> cls, boolean deserialize) {
-        PortableClassDescriptor desc;
-
-        String clsName = cls.getName();
-
-        if (marshCtx.isSystemType(clsName)) {
-            desc = new PortableClassDescriptor(this,
-                cls,
-                false,
-                clsName.hashCode(),
-                clsName,
-                null,
-                BinaryInternalIdMapper.defaultInstance(),
-                null,
-                false,
-                true, /* registered */
-                false /* predefined */
-            );
-
-            PortableClassDescriptor old = descByCls.putIfAbsent(cls, desc);
-
-            if (old != null)
-                desc = old;
-        }
-        else
-            desc = registerUserClassDescriptor(cls, deserialize);
-
-        return desc;
-    }
-
-    /**
-     * Creates and registers {@link PortableClassDescriptor} for the given user {@code class}.
-     *
-     * @param cls Class.
-     * @return Class descriptor.
-     */
-    private PortableClassDescriptor registerUserClassDescriptor(Class<?> cls, boolean deserialize) {
-        boolean registered;
-
-        String typeName = typeName(cls.getName());
-
-        BinaryIdMapper idMapper = userTypeIdMapper(typeName);
-
-        int typeId = idMapper.typeId(typeName);
-
-        try {
-            registered = marshCtx.registerClass(typeId, cls);
-        }
-        catch (IgniteCheckedException e) {
-            throw new BinaryObjectException("Failed to register class.", e);
-        }
-
-        String affFieldName = affinityFieldName(cls);
-
-        PortableClassDescriptor desc = new PortableClassDescriptor(this,
-            cls,
-            true,
-            typeId,
-            typeName,
-            affFieldName,
-            idMapper,
-            null,
-            true,
-            registered,
-            false /* predefined */
-        );
-
-        if (!deserialize) {
-            Collection<PortableSchema> schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
-
-            metaHnd.addMeta(typeId,
-                new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this));
-        }
-
-        // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader
-        // might have reloaded described class.
-        if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
-            userTypes.put(typeId, desc);
-
-        descByCls.put(cls, desc);
-
-        mappers.putIfAbsent(typeId, idMapper);
-
-        return desc;
-    }
-
-    /**
-     * @param cls Collection class.
-     * @return Collection type ID.
-     */
-    public byte collectionType(Class<? extends Collection> cls) {
-        assert cls != null;
-
-        Byte type = colTypes.get(cls);
-
-        if (type != null)
-            return type;
-
-        return Set.class.isAssignableFrom(cls) ? GridPortableMarshaller.USER_SET : GridPortableMarshaller.USER_COL;
-    }
-
-    /**
-     * @param cls Map class.
-     * @return Map type ID.
-     */
-    public byte mapType(Class<? extends Map> cls) {
-        assert cls != null;
-
-        Byte type = mapTypes.get(cls);
-
-        return type != null ? type : GridPortableMarshaller.USER_COL;
-    }
-
-    /**
-     * @param typeName Type name.
-     * @return Type ID.
-     */
-    public int typeId(String typeName) {
-        String typeName0 = typeName(typeName);
-
-        Integer id = predefinedTypeNames.get(typeName0);
-
-        if (id != null)
-            return id;
-
-        if (marshCtx.isSystemType(typeName))
-            return typeName.hashCode();
-
-        return userTypeIdMapper(typeName0).typeId(typeName0);
-    }
-
-    /**
-     * @param typeId Type ID.
-     * @param fieldName Field name.
-     * @return Field ID.
-     */
-    public int fieldId(int typeId, String fieldName) {
-        return userTypeIdMapper(typeId).fieldId(typeId, fieldName);
-    }
-
-    /**
-     * @param typeId Type ID.
-     * @return Instance of ID mapper.
-     */
-    public BinaryIdMapper userTypeIdMapper(int typeId) {
-        BinaryIdMapper idMapper = mappers.get(typeId);
-
-        return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance();
-    }
-
-    /**
-     * @param typeName Type name.
-     * @return Instance of ID mapper.
-     */
-    private BinaryIdMapper userTypeIdMapper(String typeName) {
-        BinaryIdMapper idMapper = typeMappers.get(typeName);
-
-        return idMapper != null ? idMapper : BinaryInternalIdMapper.defaultInstance();
-    }
-
-    /**
-     * @param cls Class to get affinity field for.
-     * @return Affinity field name or {@code null} if field name was not found.
-     */
-    private String affinityFieldName(Class cls) {
-        for (; cls != Object.class && cls != null; cls = cls.getSuperclass()) {
-            for (Field f : cls.getDeclaredFields()) {
-                if (f.getAnnotation(AffinityKeyMapped.class) != null)
-                    return f.getName();
-            }
-        }
-
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void writeExternal(ObjectOutput out) throws IOException {
-        U.writeString(out, igniteCfg.getGridName());
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        gridName = U.readString(in);
-    }
-
-    /**
-     * @return Portable context.
-     * @throws ObjectStreamException In case of error.
-     */
-    protected Object readResolve() throws ObjectStreamException {
-        try {
-            IgniteKernal g = IgnitionEx.gridx(gridName);
-
-            if (g == null)
-                throw new IllegalStateException("Failed to find grid for name: " + gridName);
-
-            return ((CacheObjectBinaryProcessorImpl)g.context().cacheObjects()).portableContext();
-        }
-        catch (IllegalStateException e) {
-            throw U.withCause(new InvalidObjectException(e.getMessage()), e);
-        }
-    }
-
-    /**
-     * @param cls Class.
-     * @param id Type ID.
-     * @return GridPortableClassDescriptor.
-     */
-    public PortableClassDescriptor registerPredefinedType(Class<?> cls, int id) {
-        String typeName = typeName(cls.getName());
-
-        PortableClassDescriptor desc = new PortableClassDescriptor(
-            this,
-            cls,
-            false,
-            id,
-            typeName,
-            null,
-            BinaryInternalIdMapper.defaultInstance(),
-            null,
-            false,
-            true, /* registered */
-            true /* predefined */
-        );
-
-        predefinedTypeNames.put(typeName, id);
-        predefinedTypes.put(id, desc);
-
-        descByCls.put(cls, desc);
-
-        return desc;
-    }
-
-    /**
-     * @param clsName Class name.
-     * @param idMapper ID mapper.
-     * @param serializer Serializer.
-     * @param affKeyFieldName Affinity key field name.
-     * @param isEnum If enum.
-     * @throws BinaryObjectException In case of error.
-     */
-    @SuppressWarnings("ErrorNotRethrown")
-    public void registerUserType(String clsName,
-        BinaryIdMapper idMapper,
-        @Nullable BinarySerializer serializer,
-        @Nullable String affKeyFieldName,
-        boolean isEnum)
-        throws BinaryObjectException {
-        assert idMapper != null;
-
-        Class<?> cls = null;
-
-        try {
-            cls = Class.forName(clsName);
-        }
-        catch (ClassNotFoundException | NoClassDefFoundError ignored) {
-            // No-op.
-        }
-
-        String typeName = typeName(clsName);
-
-        int id = idMapper.typeId(typeName);
-
-        //Workaround for IGNITE-1358
-        if (predefinedTypes.get(id) != null)
-            throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
-
-        if (mappers.put(id, idMapper) != null)
-            throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
-
-        if (affKeyFieldName != null) {
-            if (affKeyFieldNames.put(id, affKeyFieldName) != null)
-                throw new BinaryObjectException("Duplicate type ID [clsName=" + clsName + ", id=" + id + ']');
-        }
-
-        typeMappers.put(typeName, idMapper);
-
-        Map<String, Integer> fieldsMeta = null;
-        Collection<PortableSchema> schemas = null;
-
-        if (cls != null) {
-            PortableClassDescriptor desc = new PortableClassDescriptor(
-                this,
-                cls,
-                true,
-                id,
-                typeName,
-                affKeyFieldName,
-                idMapper,
-                serializer,
-                true,
-                true, /* registered */
-                false /* predefined */
-            );
-
-            fieldsMeta = desc.fieldsMeta();
-            schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
-
-            if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
-                userTypes.put(id, desc);
-
-            descByCls.put(cls, desc);
-        }
-
-        metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, schemas, isEnum).wrap(this));
-    }
-
-    /**
-     * Create binary field.
-     *
-     * @param typeId Type ID.
-     * @param fieldName Field name.
-     * @return Binary field.
-     */
-    public BinaryFieldImpl createField(int typeId, String fieldName) {
-        PortableSchemaRegistry schemaReg = schemaRegistry(typeId);
-
-        int fieldId = userTypeIdMapper(typeId).fieldId(typeId, fieldName);
-
-        return new BinaryFieldImpl(typeId, schemaReg, fieldName, fieldId);
-    }
-
-    /**
-     * @param typeId Type ID.
-     * @return Meta data.
-     * @throws BinaryObjectException In case of error.
-     */
-    @Nullable public BinaryType metadata(int typeId) throws BinaryObjectException {
-        return metaHnd != null ? metaHnd.metadata(typeId) : null;
-    }
-
-    /**
-     * @param typeId Type ID.
-     * @return Affinity key field name.
-     */
-    public String affinityKeyFieldName(int typeId) {
-        return affKeyFieldNames.get(typeId);
-    }
-
-    /**
-     * @param typeId Type ID.
-     * @param meta Meta data.
-     * @throws BinaryObjectException In case of error.
-     */
-    public void updateMetadata(int typeId, BinaryMetadata meta) throws BinaryObjectException {
-        metaHnd.addMeta(typeId, meta.wrap(this));
-    }
-
-    /**
-     * @return Whether field IDs should be skipped in footer or not.
-     */
-    public boolean isCompactFooter() {
-        return compactFooter;
-    }
-
-    /**
-     * Get schema registry for type ID.
-     *
-     * @param typeId Type ID.
-     * @return Schema registry for type ID.
-     */
-    public PortableSchemaRegistry schemaRegistry(int typeId) {
-        Map<Integer, PortableSchemaRegistry> schemas0 = schemas;
-
-        if (schemas0 == null) {
-            synchronized (this) {
-                schemas0 = schemas;
-
-                if (schemas0 == null) {
-                    schemas0 = new HashMap<>();
-
-                    PortableSchemaRegistry reg = new PortableSchemaRegistry();
-
-                    schemas0.put(typeId, reg);
-
-                    schemas = schemas0;
-
-                    return reg;
-                }
-            }
-        }
-
-        PortableSchemaRegistry reg = schemas0.get(typeId);
-
-        if (reg == null) {
-            synchronized (this) {
-                reg = schemas.get(typeId);
-
-                if (reg == null) {
-                    reg = new PortableSchemaRegistry();
-
-                    schemas0 = new HashMap<>(schemas);
-
-                    schemas0.put(typeId, reg);
-
-                    schemas = schemas0;
-                }
-            }
-        }
-
-        return reg;
-    }
-
-    /**
-     * Returns instance of {@link OptimizedMarshaller}.
-     *
-     * @return Optimized marshaller.
-     */
-    OptimizedMarshaller optimizedMarsh() {
-        return optmMarsh;
-    }
-
-    /**
-     * @param clsName Class name.
-     * @return Type name.
-     */
-    @SuppressWarnings("ResultOfMethodCallIgnored")
-    public static String typeName(String clsName) {
-        assert clsName != null;
-
-        int idx = clsName.lastIndexOf('$');
-
-        if (idx == clsName.length() - 1)
-            // This is a regular (not inner) class name that ends with '$'. Common use case for Scala classes.
-            idx = -1;
-        else if (idx >= 0) {
-            String typeName = clsName.substring(idx + 1);
-
-            try {
-                Integer.parseInt(typeName);
-
-                // This is an anonymous class. Don't cut off enclosing class name for it.
-                idx = -1;
-            }
-            catch (NumberFormatException ignore) {
-                // This is a lambda class.
-                if (clsName.indexOf("$$Lambda$") > 0)
-                    idx = -1;
-                else
-                    return typeName;
-            }
-        }
-
-        if (idx < 0)
-            idx = clsName.lastIndexOf('.');
-
-        return idx >= 0 ? clsName.substring(idx + 1) : clsName;
-    }
-
-    /**
-     * Undeployment callback invoked when class loader is being undeployed.
-     *
-     * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow.
-     *
-     * @param ldr Class loader being undeployed.
-     */
-    public void onUndeploy(ClassLoader ldr) {
-        for (Class<?> cls : descByCls.keySet()) {
-            if (ldr.equals(cls.getClassLoader()))
-                descByCls.remove(cls);
-        }
-
-        U.clearClassCache(ldr);
-    }
-
-    /**
-     * Type descriptors.
-     */
-    private static class TypeDescriptors {
-        /** Descriptors map. */
-        private final Map<String, TypeDescriptor> descs = new LinkedHashMap<>();
-
-        /**
-         * Add type descriptor.
-         *
-         * @param clsName Class name.
-         * @param idMapper ID mapper.
-         * @param serializer Serializer.
-         * @param affKeyFieldName Affinity key field name.
-         * @param isEnum Enum flag.
-         * @param canOverride Whether this descriptor can be override.
-         * @throws BinaryObjectException If failed.
-         */
-        private void add(String clsName,
-            BinaryIdMapper idMapper,
-            BinarySerializer serializer,
-            String affKeyFieldName,
-            boolean isEnum,
-            boolean canOverride)
-            throws BinaryObjectException {
-            TypeDescriptor desc = new TypeDescriptor(clsName,
-                idMapper,
-                serializer,
-                affKeyFieldName,
-                isEnum,
-                canOverride);
-
-            TypeDescriptor oldDesc = descs.get(clsName);
-
-            if (oldDesc == null)
-                descs.put(clsName, desc);
-            else
-                oldDesc.override(desc);
-        }
-
-        /**
-         * Get all collected descriptors.
-         *
-         * @return Descriptors.
-         */
-        private Iterable<TypeDescriptor> descriptors() {
-            return descs.values();
-        }
-    }
-
-    /**
-     * Type descriptor.
-     */
-    private static class TypeDescriptor {
-        /** Class name. */
-        private final String clsName;
-
-        /** ID mapper. */
-        private BinaryIdMapper idMapper;
-
-        /** Serializer. */
-        private BinarySerializer serializer;
-
-        /** Affinity key field name. */
-        private String affKeyFieldName;
-
-        /** Enum flag. */
-        private boolean isEnum;
-
-        /** Whether this descriptor can be override. */
-        private boolean canOverride;
-
-        /**
-         * Constructor.
-         *
-         * @param clsName Class name.
-         * @param idMapper ID mapper.
-         * @param serializer Serializer.
-         * @param affKeyFieldName Affinity key field name.
-         * @param isEnum Enum type.
-         * @param canOverride Whether this descriptor can be override.
-         */
-        private TypeDescriptor(String clsName, BinaryIdMapper idMapper, BinarySerializer serializer,
-            String affKeyFieldName, boolean isEnum, boolean canOverride) {
-            this.clsName = clsName;
-            this.idMapper = idMapper;
-            this.serializer = serializer;
-            this.affKeyFieldName = affKeyFieldName;
-            this.isEnum = isEnum;
-            this.canOverride = canOverride;
-        }
-
-        /**
-         * Override portable class descriptor.
-         *
-         * @param other Other descriptor.
-         * @throws BinaryObjectException If failed.
-         */
-        private void override(TypeDescriptor other) throws BinaryObjectException {
-            assert clsName.equals(other.clsName);
-
-            if (canOverride) {
-                idMapper = other.idMapper;
-                serializer = other.serializer;
-                affKeyFieldName = other.affKeyFieldName;
-                canOverride = other.canOverride;
-            }
-            else if (!other.canOverride)
-                throw new BinaryObjectException("Duplicate explicit class definition in configuration: " + clsName);
-        }
-    }
-
-    /**
-     * Type id wrapper.
-     */
-    static class Type {
-        /** Type id */
-        private final int id;
-
-        /** Whether the following type is registered in a cache or not */
-        private final boolean registered;
-
-        /**
-         * @param id Id.
-         * @param registered Registered.
-         */
-        public Type(int id, boolean registered) {
-            this.id = id;
-            this.registered = registered;
-        }
-
-        /**
-         * @return Type ID.
-         */
-        public int id() {
-            return id;
-        }
-
-        /**
-         * @return Registered flag value.
-         */
-        public boolean registered() {
-            return registered;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
deleted file mode 100644
index c49c898..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePositionReadable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-/**
- * Interface allowing for positioned read.
- */
-public interface PortablePositionReadable {
-    /**
-     * Read byte at the given position.
-     *
-     * @param pos Position.
-     * @return Value.
-     */
-    public byte readBytePositioned(int pos);
-
-    /**
-     * Read short at the given position.
-     *
-     * @param pos Position.
-     * @return Value.
-     */
-    public short readShortPositioned(int pos);
-
-    /**
-     * Read integer at the given position.
-     *
-     * @param pos Position.
-     * @return Value.
-     */
-    public int readIntPositioned(int pos);
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
deleted file mode 100644
index 02f552a..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import org.apache.ignite.internal.util.GridUnsafe;
-import sun.misc.Unsafe;
-
-import java.nio.ByteOrder;
-
-/**
- * Primitives writer.
- */
-public abstract class PortablePrimitives {
-    /** */
-    private static final Unsafe UNSAFE = GridUnsafe.unsafe();
-
-    /** */
-    private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
-
-    /** */
-    private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
-
-    /** Whether little endian is set. */
-    private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeByte(byte[] arr, int off, byte val) {
-        UNSAFE.putByte(arr, BYTE_ARR_OFF + off, val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static byte readByte(byte[] arr, int off) {
-        return UNSAFE.getByte(arr, BYTE_ARR_OFF + off);
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static byte readByte(long ptr, int off) {
-        return UNSAFE.getByte(ptr + off);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static byte[] readByteArray(byte[] arr, int off, int len) {
-        byte[] arr0 = new byte[len];
-
-        UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, BYTE_ARR_OFF, len);
-
-        return arr0;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static byte[] readByteArray(long ptr, int off, int len) {
-        byte[] arr0 = new byte[len];
-
-        UNSAFE.copyMemory(null, ptr + off, arr0, BYTE_ARR_OFF, len);
-
-        return arr0;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeBoolean(byte[] arr, int off, boolean val) {
-        writeByte(arr, off, val ? (byte)1 : (byte)0);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static boolean readBoolean(byte[] arr, int off) {
-        return readByte(arr, off) == 1;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static boolean readBoolean(long ptr, int off) {
-        return readByte(ptr, off) == 1;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeShort(byte[] arr, int off, short val) {
-        if (BIG_ENDIAN)
-            val = Short.reverseBytes(val);
-
-        UNSAFE.putShort(arr, BYTE_ARR_OFF + off, val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static short readShort(byte[] arr, int off) {
-        short val = UNSAFE.getShort(arr, BYTE_ARR_OFF + off);
-
-        if (BIG_ENDIAN)
-            val = Short.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static short readShort(long ptr, int off) {
-        short val = UNSAFE.getShort(ptr + off);
-
-        if (BIG_ENDIAN)
-            val = Short.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeChar(byte[] arr, int off, char val) {
-        if (BIG_ENDIAN)
-            val = Character.reverseBytes(val);
-
-        UNSAFE.putChar(arr, BYTE_ARR_OFF + off, val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static char readChar(byte[] arr, int off) {
-        char val = UNSAFE.getChar(arr, BYTE_ARR_OFF + off);
-
-        if (BIG_ENDIAN)
-            val = Character.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static char readChar(long ptr, int off) {
-        char val = UNSAFE.getChar(ptr + off);
-
-        if (BIG_ENDIAN)
-            val = Character.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static char[] readCharArray(byte[] arr, int off, int len) {
-        char[] arr0 = new char[len];
-
-        UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, CHAR_ARR_OFF, len << 1);
-
-        if (BIG_ENDIAN) {
-            for (int i = 0; i < len; i++)
-                arr0[i] = Character.reverseBytes(arr0[i]);
-        }
-
-        return arr0;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static char[] readCharArray(long ptr, int off, int len) {
-        char[] arr0 = new char[len];
-
-        UNSAFE.copyMemory(null, ptr + off, arr0, CHAR_ARR_OFF, len << 1);
-
-        if (BIG_ENDIAN) {
-            for (int i = 0; i < len; i++)
-                arr0[i] = Character.reverseBytes(arr0[i]);
-        }
-
-        return arr0;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeInt(byte[] arr, int off, int val) {
-        if (BIG_ENDIAN)
-            val = Integer.reverseBytes(val);
-
-        UNSAFE.putInt(arr, BYTE_ARR_OFF + off, val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static int readInt(byte[] arr, int off) {
-        int val = UNSAFE.getInt(arr, BYTE_ARR_OFF + off);
-
-        if (BIG_ENDIAN)
-            val = Integer.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static int readInt(long ptr, int off) {
-        int val = UNSAFE.getInt(ptr + off);
-
-        if (BIG_ENDIAN)
-            val = Integer.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeLong(byte[] arr, int off, long val) {
-        if (BIG_ENDIAN)
-            val = Long.reverseBytes(val);
-
-        UNSAFE.putLong(arr, BYTE_ARR_OFF + off, val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static long readLong(byte[] arr, int off) {
-        long val = UNSAFE.getLong(arr, BYTE_ARR_OFF + off);
-
-        if (BIG_ENDIAN)
-            val = Long.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static long readLong(long ptr, int off) {
-        long val = UNSAFE.getLong(ptr + off);
-
-        if (BIG_ENDIAN)
-            val = Long.reverseBytes(val);
-
-        return val;
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeFloat(byte[] arr, int off, float val) {
-        int val0 = Float.floatToIntBits(val);
-
-        writeInt(arr, off, val0);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static float readFloat(byte[] arr, int off) {
-        int val = readInt(arr, off);
-
-        return Float.intBitsToFloat(val);
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static float readFloat(long ptr, int off) {
-        int val = readInt(ptr, off);
-
-        return Float.intBitsToFloat(val);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @param val Value.
-     */
-    public static void writeDouble(byte[] arr, int off, double val) {
-        long val0 = Double.doubleToLongBits(val);
-
-        writeLong(arr, off, val0);
-    }
-
-    /**
-     * @param arr Array.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static double readDouble(byte[] arr, int off) {
-        long val = readLong(arr, off);
-
-        return Double.longBitsToDouble(val);
-    }
-
-    /**
-     * @param ptr Pointer.
-     * @param off Offset.
-     * @return Value.
-     */
-    public static double readDouble(long ptr, int off) {
-        long val = readLong(ptr, off);
-
-        return Double.longBitsToDouble(val);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1dbf20e0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
deleted file mode 100644
index 72a96b9..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableSchema.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.portable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Schema describing portable object content. We rely on the following assumptions:
- * - When amount of fields in the object is low, it is better to inline these values into int fields thus allowing
- * for quick comparisons performed within already fetched L1 cache line.
- * - When there are more fields, we store them inside a hash map.
- */
-public class PortableSchema implements Externalizable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Order returned if field is not found. */
-    public static final int ORDER_NOT_FOUND = -1;
-
-    /** Minimum sensible size. */
-    private static final int MAP_MIN_SIZE = 32;
-
-    /** Empty cell. */
-    private static final int MAP_EMPTY = 0;
-
-    /** Schema ID. */
-    private int schemaId;
-
-    /** IDs depending on order. */
-    private int[] ids;
-
-    /** Interned names of associated fields. */
-    private String[] names;
-
-    /** ID-to-order data. */
-    private int[] idToOrderData;
-
-    /** ID-to-order mask. */
-    private int idToOrderMask;
-
-    /** ID 1. */
-    private int id0;
-
-    /** ID 2. */
-    private int id1;
-
-    /** ID 3. */
-    private int id2;
-
-    /** ID 4. */
-    private int id3;
-
-    /**
-     * {@link Externalizable} support.
-     */
-    public PortableSchema() {
-        // No-op.
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param schemaId Schema ID.
-     * @param fieldIds Field IDs.
-     */
-    private PortableSchema(int schemaId, List<Integer> fieldIds) {
-        assert fieldIds != null;
-
-        this.schemaId = schemaId;
-
-        initialize(fieldIds);
-    }
-
-    /**
-     * @return Schema ID.
-     */
-    public int schemaId() {
-        return schemaId;
-    }
-
-    /**
-     * Try speculatively confirming order for the given field name.
-     *
-     * @param expOrder Expected order.
-     * @param expName Expected name.
-     * @return Field ID.
-     */
-    @SuppressWarnings("StringEquality")
-    public Confirmation confirmOrder(int expOrder, String expName) {
-        assert expName != null;
-
-        if (expOrder < names.length) {
-            String name = names[expOrder];
-
-            // Note that we use only reference equality assuming that field names are interned literals.
-            if (name == expName)
-                return Confirmation.CONFIRMED;
-
-            if (name == null)
-                return Confirmation.CLARIFY;
-        }
-
-        return Confirmation.REJECTED;
-    }
-
-    /**
-     * Add field name.
-     *
-     * @param order Order.
-     * @param name Name.
-     */
-    public void clarifyFieldName(int order, String name) {
-        assert name != null;
-        assert order < names.length;
-
-        names[order] = name.intern();
-    }
-
-    /**
-     * Get field ID by order in footer.
-     *
-     * @param order Order.
-     * @return Field ID.
-     */
-    public int fieldId(int order) {
-        return order < ids.length ? ids[order] : 0;
-    }
-
-    /**
-     * Get field order in footer by field ID.
-     *
-     * @param id Field ID.
-     * @return Offset or {@code 0} if there is no such field.
-     */
-    public int order(int id) {
-        if (idToOrderData == null) {
-            if (id == id0)
-                return 0;
-
-            if (id == id1)
-                return 1;
-
-            if (id == id2)
-                return 2;
-
-            if (id == id3)
-                return 3;
-
-            return ORDER_NOT_FOUND;
-        }
-        else {
-            int idx = (id & idToOrderMask) << 1;
-
-            int curId = idToOrderData[idx];
-
-            if (id == curId) // Hit!
-                return idToOrderData[idx + 1];
-            else if (curId == MAP_EMPTY) // No such ID!
-                return ORDER_NOT_FOUND;
-            else {
-                // Unlikely collision scenario.
-                for (int i = 2; i < idToOrderData.length; i += 2) {
-                    int newIdx = (idx + i) % idToOrderData.length;
-
-                    assert newIdx < idToOrderData.length - 1;
-
-                    curId = idToOrderData[newIdx];
-
-                    if (id == curId)
-                        return idToOrderData[newIdx + 1];
-                    else if (curId == MAP_EMPTY)
-                        return ORDER_NOT_FOUND;
-                }
-
-                return ORDER_NOT_FOUND;
-            }
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return schemaId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        return o != null && o instanceof PortableSchema && schemaId == ((PortableSchema)o).schemaId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeInt(schemaId);
-
-        out.writeInt(ids.length);
-
-        for (Integer id : ids)
-            out.writeInt(id);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        schemaId = in.readInt();
-
-        int idsCnt = in.readInt();
-
-        List<Integer> fieldIds = new ArrayList<>(idsCnt);
-
-        for (int i = 0; i < idsCnt; i++)
-            fieldIds.add(in.readInt());
-
-        initialize(fieldIds);
-    }
-
-    /**
-     * Parse values.
-     *
-     * @param vals Values.
-     * @param size Proposed result size.
-     * @return Parse result.
-     */
-    private static ParseResult parse(int[] vals, int size) {
-        int mask = maskForPowerOfTwo(size);
-
-        int totalSize = size * 2;
-
-        int[] data = new int[totalSize];
-        int collisions = 0;
-
-        for (int order = 0; order < vals.length; order++) {
-            int id = vals[order];
-
-            assert id != 0;
-
-            int idIdx = (id & mask) << 1;
-
-            if (data[idIdx] == 0) {
-                // Found empty slot.
-                data[idIdx] = id;
-                data[idIdx + 1] = order;
-            }
-            else {
-                // Collision!
-                collisions++;
-
-                boolean placeFound = false;
-
-                for (int i = 2; i < totalSize; i += 2) {
-                    int newIdIdx = (idIdx + i) % totalSize;
-
-                    if (data[newIdIdx] == 0) {
-                        data[newIdIdx] = id;
-                        data[newIdIdx + 1] = order;
-
-                        placeFound = true;
-
-                        break;
-                    }
-                }
-
-                assert placeFound : "Should always have a place for entry!";
-            }
-        }
-
-        return new ParseResult(data, collisions);
-    }
-
-    /**
-     * Get next power of two which greater or equal to the given number.
-     * This implementation is not meant to be very efficient, so it is expected to be used relatively rare.
-     *
-     * @param val Number
-     * @return Nearest pow2.
-     */
-    private static int nextPowerOfTwo(int val) {
-        int res = 1;
-
-        while (res < val)
-            res = res << 1;
-
-        if (res < 0)
-            throw new IllegalArgumentException("Value is too big to find positive pow2: " + val);
-
-        return res;
-    }
-
-    /**
-     * Calculate mask for the given value which is a power of two.
-     *
-     * @param val Value.
-     * @return Mask.
-     */
-    private static int maskForPowerOfTwo(int val) {
-        int mask = 0;
-        int comparand = 1;
-
-        while (comparand < val) {
-            mask |= comparand;
-
-            comparand <<= 1;
-        }
-
-        return mask;
-    }
-
-    /**
-     * Initialization routine.
-     *
-     * @param fieldIds Field IDs.
-     */
-    private void initialize(List<Integer> fieldIds) {
-        ids = new int[fieldIds.size()];
-
-        for (int i = 0; i < fieldIds.size(); i++)
-            ids[i] = fieldIds.get(i);
-
-        names = new String[fieldIds.size()];
-
-        if (fieldIds.size() <= 4) {
-            Iterator<Integer> iter = fieldIds.iterator();
-
-            id0 = iter.hasNext() ? iter.next() : 0;
-            id1 = iter.hasNext() ? iter.next() : 0;
-            id2 = iter.hasNext() ? iter.next() : 0;
-            id3 = iter.hasNext() ? iter.next() : 0;
-        }
-        else {
-            id0 = id1 = id2 = id3 = 0;
-
-            initializeMap(ids);
-        }
-    }
-
-    /**
-     * Initialize the map.
-     *
-     * @param vals Values.
-     */
-    private void initializeMap(int[] vals) {
-        int size = Math.max(nextPowerOfTwo(vals.length) << 2, MAP_MIN_SIZE);
-
-        assert size > 0;
-
-        ParseResult finalRes;
-
-        ParseResult res1 = parse(vals, size);
-
-        if (res1.collisions == 0)
-            finalRes = res1;
-        else {
-            ParseResult res2 = parse(vals, size * 2);
-
-            // Failed to decrease aom
-            if (res2.collisions == 0)
-                finalRes = res2;
-            else
-                finalRes = parse(vals, size * 4);
-        }
-
-        idToOrderData = finalRes.data;
-        idToOrderMask = maskForPowerOfTwo(idToOrderData.length / 2);
-    }
-
-    /**
-     * Schema builder.
-     */
-    public static class Builder {
-        /** Schema ID. */
-        private int schemaId = PortableUtils.schemaInitialId();
-
-        /** Fields. */
-        private final ArrayList<Integer> fields = new ArrayList<>();
-
-        /**
-         * Create new schema builder.
-         *
-         * @return Schema builder.
-         */
-        public static Builder newBuilder() {
-            return new Builder();
-        }
-
-        /**
-         * Private constructor.
-         */
-        private Builder() {
-            // No-op.
-        }
-
-        /**
-         * Add field.
-         *
-         * @param fieldId Field ID.
-         */
-        public void addField(int fieldId) {
-            fields.add(fieldId);
-
-            schemaId = PortableUtils.updateSchemaId(schemaId, fieldId);
-        }
-
-        /**
-         * Build schema.
-         *
-         * @return Schema.
-         */
-        public PortableSchema build() {
-            return new PortableSchema(schemaId, fields);
-        }
-    }
-
-    /**
-     * Order confirmation result.
-     */
-    public enum Confirmation {
-        /** Confirmed. */
-        CONFIRMED,
-
-        /** Denied. */
-        REJECTED,
-
-        /** Field name clarification is needed. */
-        CLARIFY
-    }
-
-    /**
-     * Result of map parsing.
-     */
-    private static class ParseResult {
-        /** Data. */
-        private int[] data;
-
-        /** Collisions. */
-        private int collisions;
-
-        /**
-         * Constructor.
-         *
-         * @param data Data.
-         * @param collisions Collisions.
-         */
-        private ParseResult(int[] data, int collisions) {
-            this.data = data;
-            this.collisions = collisions;
-        }
-    }
-}