You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2015/10/30 16:52:46 UTC

[50/52] [abbrv] ignite git commit: IGNITE-950-new Fixed compilation.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectReaderExImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectReaderExImpl.java
index b018f7d,0000000..38a8a58
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectReaderExImpl.java
@@@ -1,3230 -1,0 +1,2765 @@@
 +/*
 + * 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.internal.portable.streams.PortableHeapInputStream;
 +import org.apache.ignite.internal.portable.streams.PortableInputStream;
 +import org.apache.ignite.internal.util.GridEnumCache;
 +import org.apache.ignite.internal.util.lang.GridMapEntry;
 +import org.apache.ignite.internal.util.typedef.internal.SB;
 +import org.apache.ignite.internal.util.typedef.internal.U;
 +import org.apache.ignite.igniteobject.IgniteObjectException;
 +import org.apache.ignite.igniteobject.IgniteObjectInvalidClassException;
 +import org.apache.ignite.igniteobject.IgniteObject;
 +import org.apache.ignite.igniteobject.IgniteObjectRawReader;
 +import org.apache.ignite.igniteobject.IgniteObjectReader;
++import org.apache.ignite.lang.IgniteBiTuple;
 +import org.jetbrains.annotations.NotNull;
 +import org.jetbrains.annotations.Nullable;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.EOFException;
 +import java.io.IOException;
 +import java.io.ObjectInput;
 +import java.lang.reflect.Array;
 +import java.lang.reflect.Constructor;
 +import java.lang.reflect.InvocationTargetException;
 +import java.math.BigDecimal;
 +import java.math.BigInteger;
 +import java.sql.Timestamp;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.Date;
++import java.util.LinkedHashMap;
 +import java.util.LinkedList;
 +import java.util.Map;
 +import java.util.Properties;
 +import java.util.TreeMap;
 +import java.util.TreeSet;
 +import java.util.UUID;
 +import java.util.concurrent.ConcurrentHashMap;
 +import java.util.concurrent.ConcurrentSkipListSet;
 +
 +import static java.nio.charset.StandardCharsets.UTF_8;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.ARR_LIST;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLASS;
- import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLS_NAME_POS;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.COL;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CONC_HASH_MAP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CONC_SKIP_LIST_SET;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.HANDLE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_MAP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_SET;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LINKED_HASH_MAP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LINKED_HASH_SET;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LINKED_LIST;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP_ENTRY;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJECT_TYPE_ID;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.OPTM_MARSH;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.PORTABLE_OBJ;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROPERTIES_MAP;
- import static org.apache.ignite.internal.portable.GridPortableMarshaller.RAW_DATA_OFF_POS;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP_ARR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.TREE_MAP;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.TREE_SET;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.UNREGISTERED_TYPE_ID;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.USER_COL;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.USER_SET;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID_ARR;
 +
 +/**
 + * Portable reader implementation.
 + */
 +@SuppressWarnings("unchecked")
 +public class IgniteObjectReaderExImpl implements IgniteObjectReader, IgniteObjectRawReaderEx, ObjectInput {
++    /** Length of a single field descriptor. */
++    private static final int FIELD_DESC_LEN = 16;
++
 +    /** */
 +    private final PortableContext ctx;
 +
 +    /** */
 +    private final PortableInputStream in;
 +
 +    /** */
 +    private final int start;
 +
 +    /** */
 +    private final PortableReaderContext rCtx;
 +
 +    /** */
 +    private final ClassLoader ldr;
 +
 +    /** */
-     private int off;
++    private PortableClassDescriptor desc;
 +
-     /** */
-     private int rawOff;
++    /** Flag indicating that object header was parsed. */
++    private boolean hdrParsed;
 +
-     /** */
-     private int len;
++    /** Type ID. */
++    private int typeId;
 +
-     /** */
-     private PortableClassDescriptor desc;
++    /** Raw offset. */
++    private int rawOff;
 +
 +    /** */
 +    private int hdrLen;
 +
-     /** */
-     private int clsNameLen;
++    /** Footer start. */
++    private int footerStart;
 +
-     /** */
-     private Integer typeId;
++    /** Footer end. */
++    private int footerLen;
++
++    /** ID mapper. */
++    private PortableIdMapper idMapper;
++
++    /** Schema Id. */
++    private int schemaId;
++
++    /** Object schema. */
++    private PortableSchema schema;
 +
 +    /**
 +     * @param ctx Context.
 +     * @param arr Array.
 +     * @param start Start.
 +     * @param ldr Class loader.
 +     */
 +    public IgniteObjectReaderExImpl(PortableContext ctx, byte[] arr, int start, ClassLoader ldr) {
 +        this(ctx, new PortableHeapInputStream(arr), start, ldr, new PortableReaderContext());
 +    }
 +
 +    /**
 +     * @param ctx Context.
 +     * @param in Input stream.
 +     * @param start Start.
 +     */
 +    IgniteObjectReaderExImpl(PortableContext ctx, PortableInputStream in, int start, ClassLoader ldr) {
 +        this(ctx, in, start, ldr, new PortableReaderContext());
 +    }
 +
 +    /**
 +     * @param ctx Context.
 +     * @param in Input stream.
 +     * @param start Start.
 +     * @param rCtx Context.
 +     */
 +    IgniteObjectReaderExImpl(PortableContext ctx, PortableInputStream in, int start, ClassLoader ldr,
 +        PortableReaderContext rCtx) {
 +        this.ctx = ctx;
 +        this.in = in;
 +        this.start = start;
 +        this.ldr = ldr;
 +        this.rCtx = rCtx;
 +
-         off = start;
-         rawOff = start;
++        in.position(start);
 +    }
 +
 +    /**
 +     * Preloads typeId from the input array.
 +     */
-     private void readObjectTypeId(boolean skipObjByte) {
-         int pos = rawOff;
++    private void parseHeaderIfNeeded() {
++        if (hdrParsed)
++            return;
++
++        int retPos = in.position();
++
++        in.position(start);
++
++        byte hdr = in.readByte();
 +
-         if (!skipObjByte)
-             // skip obj type byte
-             rawOff++;
++        if (hdr != GridPortableMarshaller.OBJ)
++            throw new PortableException("Invalid header [pos=" + retPos + "expected=" + GridPortableMarshaller.OBJ +
++                ", actual=" + hdr + ']');
 +
-         // Validate protocol version.
-         PortableUtils.checkProtocolVersion(doReadByte(true));
++        PortableUtils.checkProtocolVersion(in.readByte());
 +
-         // skip user flag
-         rawOff += 1;
++        in.position(in.position() + 2); // Skip flags.
 +
-         typeId = doReadInt(true);
++        typeId = in.readIntPositioned(start + GridPortableMarshaller.TYPE_ID_POS);
++
++        IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(in, start);
++
++        footerStart = footer.get1();
++        footerLen = footer.get2() - footerStart;
++
++        schemaId = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_ID_POS);
++
++        rawOff = PortableUtils.rawOffsetAbsolute(in, start);
 +
 +        if (typeId == UNREGISTERED_TYPE_ID) {
-             // skip hash code, length and raw offset
-             rawOff += 12;
++            // Skip to the class name position.
++            in.position(start + GridPortableMarshaller.DFLT_HDR_LEN);
 +
-             int off = rawOff;
++            int off = in.position();
 +
-             Class cls = doReadClass(true, typeId);
++            Class cls = doReadClass(typeId);
 +
 +            // registers class by typeId, at least locally if the cache is not ready yet.
 +            PortableClassDescriptor desc = ctx.descriptorForClass(cls);
 +
 +            typeId = desc.typeId();
 +
-             clsNameLen = rawOff - off;
++            int clsNameLen = in.position() - off;
 +
-             hdrLen = CLS_NAME_POS + clsNameLen;
++            hdrLen = DFLT_HDR_LEN + clsNameLen;
 +        }
 +        else
 +            hdrLen = DFLT_HDR_LEN;
 +
-         in.position(rawOff = pos);
++        // Restore state.
++        in.position(retPos);
++
++        hdrParsed = true;
 +    }
 +
 +    /**
 +     * @return Descriptor.
 +     */
 +    PortableClassDescriptor descriptor() {
 +        return desc;
 +    }
 +
 +    /**
 +     * @return Unmarshalled value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Object unmarshal() throws IgniteObjectException {
-         return unmarshal(true);
++        return unmarshal(false);
++    }
++
++    /**
++     * @param offset Offset in the array.
++     * @return Unmarshalled value.
++     * @throws PortableException In case of error.
++     */
++    public Object unmarshal(int offset) throws PortableException {
++        in.position(offset);
++
++        return in.position() >= 0 ? unmarshal() : null;
 +    }
 +
 +    /**
 +     * @param fieldName Field name.
 +     * @return Unmarshalled value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
-     @Nullable Object unmarshal(String fieldName) throws IgniteObjectException {
-         off = fieldOffset(fieldId(fieldName));
++    @Nullable Object unmarshalField(String fieldName) throws IgniteObjectException {
++        return hasField(fieldName) ? unmarshal() : null;
++    }
++
++    /**
++     * @param fieldId Field ID.
++     * @return Unmarshalled value.
++     * @throws IgniteObjectException In case of error.
++     */
++    @Nullable Object unmarshalField(int fieldId) throws IgniteObjectException {
++        parseHeaderIfNeeded();
 +
-         return off >= 0 ? unmarshal(false) : null;
++        return hasField(fieldId) ? unmarshal() : null;
 +    }
 +
 +    /**
-      * @param offset Offset in the array.
++     * @param fieldOffset Field offset.
 +     * @return Unmarshalled value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
-     public Object unmarshal(int offset) throws IgniteObjectException {
-         off = offset;
++    @Nullable Object unmarshalFieldByOffset(int fieldOffset) throws IgniteObjectException {
++        assert fieldOffset != 0;
 +
-         return off >= 0 ? unmarshal(false) : null;
++        parseHeaderIfNeeded();
++
++        in.position(start + in.readIntPositioned(footerStart + fieldOffset));
++
++        return unmarshal();
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Byte readByte(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(BYTE) == Flag.NULL)
 +                return null;
 +
-             if (flag != BYTE)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadByte(false);
++            return in.readByte();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Short readShort(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(SHORT) == Flag.NULL)
 +                return null;
 +
-             if (flag != SHORT)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadShort(false);
++            return in.readShort();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Integer readInt(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(INT) == Flag.NULL)
 +                return null;
 +
-             if (flag != INT)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadInt(false);
++            return in.readInt();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Long readLong(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(LONG) == Flag.NULL)
 +                return null;
 +
-             if (flag != LONG)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadLong(false);
++            return in.readLong();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Float readFloat(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(FLOAT) == Flag.NULL)
 +                return null;
 +
-             if (flag != FLOAT)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadFloat(false);
++            return in.readFloat();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Double readDouble(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(DOUBLE) == Flag.NULL)
 +                return null;
 +
-             if (flag != DOUBLE)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDouble(false);
++            return in.readDouble();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Character readChar(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(CHAR) == Flag.NULL)
 +                return null;
 +
-             if (flag != CHAR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadChar(false);
++            return in.readChar();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Boolean readBoolean(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(BOOLEAN) == Flag.NULL)
 +                return null;
 +
-             if (flag != BOOLEAN)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadBoolean(false);
++            return in.readBoolean();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable BigDecimal readDecimal(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(DECIMAL) == Flag.NULL)
 +                return null;
 +
-             if (flag != DECIMAL)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDecimal(false);
++            return doReadDecimal();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable String readString(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(STRING) == Flag.NULL)
 +                return null;
 +
-             if (flag != STRING)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadString(false);
++            return doReadString();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable UUID readUuid(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(UUID) == Flag.NULL)
 +                return null;
 +
-             if (flag != UUID)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadUuid(false);
++            return doReadUuid();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Date readDate(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(DATE) == Flag.NULL)
 +                return null;
 +
-             if (flag != DATE)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDate(false);
++            return doReadDate();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Timestamp readTimestamp(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(TIMESTAMP) == Flag.NULL)
 +                return null;
 +
-             if (flag != TIMESTAMP)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadTimestamp(false);
++            return doReadTimestamp();
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Object readObject(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         return off >= 0 ? doReadObject(false) : null;
++        return hasField(fieldId) ? doReadObject() : null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable byte[] readByteArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(BYTE_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadByteArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != BYTE_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadByteArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable short[] readShortArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(SHORT_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadShortArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != SHORT_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadShortArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable int[] readIntArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(INT_ARR);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadIntArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != INT_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadIntArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable long[] readLongArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(LONG_ARR);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadLongArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != LONG_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadLongArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable float[] readFloatArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(FLOAT_ARR);
 +
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadFloatArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != FLOAT_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadFloatArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable double[] readDoubleArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(DOUBLE_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadDoubleArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != DOUBLE_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDoubleArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable char[] readCharArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(CHAR_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadCharArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != CHAR_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadCharArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable boolean[] readBooleanArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(BOOLEAN_ARR);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadBooleanArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != BOOLEAN_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadBooleanArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable BigDecimal[] readDecimalArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(DECIMAL_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadDecimalArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != DECIMAL_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDecimalArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable String[] readStringArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(STRING_ARR);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadStringArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != STRING_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadStringArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable UUID[] readUuidArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(UUID_ARR);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadUuidArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != UUID_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadUuidArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Date[] readDateArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(DATE_ARR);
 +
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadDateArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != DATE_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadDateArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Timestamp[] readTimestampArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(TIMESTAMP_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadTimestampArray();
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != TIMESTAMP_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadTimestampArray(false);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Object[] readObjectArray(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(OBJ_ARR);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadObjectArray(true);
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != OBJ_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadObjectArray(false, true);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @param cls Collection class.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable <T> Collection<T> readCollection(int fieldId, @Nullable Class<? extends Collection> cls)
 +        throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(COL);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return (Collection<T>)doReadCollection(true, cls);
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != COL)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return (Collection<T>)doReadCollection(false, true, cls);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @param cls Map class.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Map<?, ?> readMap(int fieldId, @Nullable Class<? extends Map> cls)
 +        throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(MAP);
 +
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadMap(true, cls);
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != MAP)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadMap(false, true, cls);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException On case of error.
 +     */
 +    @Nullable Map.Entry<?, ?> readMapEntry(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(MAP_ENTRY);
 +
-             if (flag == NULL)
-                 return null;
- 
-             if (flag == HANDLE)
++            if (flag == Flag.NORMAL)
++                return doReadMapEntry(true);
++            else if (flag == Flag.HANDLE)
 +                return readHandleField();
- 
-             if (flag != MAP_ENTRY)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return doReadMapEntry(false, true);
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Portable object.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable IgniteObject readPortableObject(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(PORTABLE_OBJ) == Flag.NULL)
 +                return null;
 +
-             if (flag != PORTABLE_OBJ)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-             return new IgniteObjectImpl(ctx, doReadByteArray(false), doReadInt(false));
++            return new IgniteObjectImpl(ctx, doReadByteArray(), in.readInt());
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @param cls Class.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Enum<?> readEnum(int fieldId, @Nullable Class<?> cls) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(ENUM) == Flag.NULL)
 +                return null;
 +
-             if (flag != ENUM)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
- 
 +            // Revisit: why have we started writing Class for enums in their serialized form?
 +            if (cls == null)
-                 cls = doReadClass(false);
++                cls = doReadClass();
 +            else
-                 doReadClass(false);
++                doReadClass();
 +
 +            Object[] vals = GridEnumCache.get(cls);
 +
-             return (Enum<?>)vals[doReadInt(false)];
++            return (Enum<?>)vals[in.readInt()];
 +        }
 +        else
 +            return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @param cls Class.
 +     * @return Value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Object[] readEnumArray(int fieldId, @Nullable Class<?> cls) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
-                 return null;
- 
-             if (flag != ENUM_ARR)
-                 throw new IgniteObjectException("Invalid flag value: " + flag);
++        if (hasField(fieldId)) {
++            Flag flag = checkFlag(ENUM_ARR);
 +
-             // Revisit: why have we started writing Class for enums in their serialized form?
-             if (cls == null)
-                 cls = doReadClass(false);
-             else
-                 doReadClass(false);
++            if (flag == Flag.NORMAL) {
++                if (cls == null)
++                    cls = doReadClass();
++                else
++                    doReadClass();
 +
-             return doReadEnumArray(false, cls);
++                return doReadEnumArray(cls);
++            }
++            else if (flag == Flag.HANDLE)
++                return readHandleField();
 +        }
-         else
-             return null;
++
++        return null;
 +    }
 +
 +    /**
 +     * @param fieldId Field ID.
 +     * @return Field class.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
 +    @Nullable Class<?> readClass(int fieldId) throws IgniteObjectException {
-         off = fieldOffset(fieldId);
- 
-         if (off >= 0) {
-             byte flag = doReadByte(false);
- 
-             if (flag == NULL)
++        if (hasField(fieldId)) {
++            if (checkFlag(CLASS) == Flag.NULL)
 +                return null;
 +
-             if (flag != CLASS)
-                 throw new IgniteObjectException("Invalid flag type: [flag=" + flag + ']');
- 
-             return doReadClass(false);
++            return doReadClass();
 +        }
 +
 +        return null;
 +    }
 +
 +    /**
 +     * @param obj Object.
 +     */
 +    void setHandler(Object obj) {
 +        rCtx.setObjectHandler(start, obj);
 +    }
 +
 +    /**
 +     * @param obj Object.
 +     * @param pos Position.
 +     */
 +    void setHandler(Object obj, int pos) {
 +        rCtx.setObjectHandler(pos, obj);
 +    }
 +
 +    /**
 +     * Recreating field value from a handle.
 +     *
 +     * @param <T> Field type.
 +     * @return Field.
 +     */
 +    private <T> T readHandleField() {
-         int handle = (off - 1) - doReadInt(false);
++        int handle = (in.position() - 1) - in.readInt();
 +
 +        Object obj = rCtx.getObjectByHandle(handle);
 +
 +        if (obj == null) {
-             off = handle;
++            in.position(handle);
 +
-             obj = doReadObject(false);
++            obj = doReadObject();
 +        }
 +
 +        return (T)obj;
 +    }
 +    /** {@inheritDoc} */
 +    @Override public byte readByte(String fieldName) throws IgniteObjectException {
 +        Byte val = readByte(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte readByte() throws IgniteObjectException {
-         return doReadByte(true);
++        return in.readByte();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public short readShort(String fieldName) throws IgniteObjectException {
 +        Short val = readShort(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public short readShort() throws IgniteObjectException {
-         return doReadShort(true);
++        return in.readShort();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int readInt(String fieldName) throws IgniteObjectException {
 +        Integer val = readInt(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int readInt() throws IgniteObjectException {
-         return doReadInt(true);
++        return in.readInt();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public long readLong(String fieldName) throws IgniteObjectException {
 +        Long val = readLong(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public long readLong() throws IgniteObjectException {
-         return doReadLong(true);
++        return in.readLong();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public float readFloat(String fieldName) throws IgniteObjectException {
 +        Float val = readFloat(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public float readFloat() throws IgniteObjectException {
-         return doReadFloat(true);
++        return in.readFloat();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public double readDouble(String fieldName) throws IgniteObjectException {
 +        Double val = readDouble(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public double readDouble() throws IgniteObjectException {
-         return doReadDouble(true);
++        return in.readDouble();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public char readChar(String fieldName) throws IgniteObjectException {
 +        Character val = readChar(fieldId(fieldName));
 +
 +        return val != null ? val : 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public char readChar() throws IgniteObjectException {
-         return doReadChar(true);
++        return in.readChar();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean readBoolean(String fieldName) throws IgniteObjectException {
 +        Boolean val = readBoolean(fieldId(fieldName));
 +
 +        return val != null ? val : false;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean readBoolean() throws IgniteObjectException {
-         return doReadBoolean(true);
++        return in.readBoolean();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override @Nullable public BigDecimal readDecimal(String fieldName) throws IgniteObjectException {
 +        return readDecimal(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override @Nullable public BigDecimal readDecimal() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(DECIMAL) == Flag.NULL)
 +            return null;
 +
-         if (flag != DECIMAL)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadDecimal(true);
++        return doReadDecimal();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public String readString(String fieldName) throws IgniteObjectException {
 +        return readString(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public String readString() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(STRING) == Flag.NULL)
 +            return null;
 +
-         if (flag != STRING)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadString(true);
++        return doReadString();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public UUID readUuid(String fieldName) throws IgniteObjectException {
 +        return readUuid(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public UUID readUuid() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(UUID) == Flag.NULL)
 +            return null;
 +
-         if (flag != UUID)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadUuid(true);
++        return doReadUuid();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Date readDate(String fieldName) throws IgniteObjectException {
 +        return readDate(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Date readDate() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(DATE) == Flag.NULL)
 +            return null;
 +
-         if (flag != DATE)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadDate(true);
++        return doReadDate();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Timestamp readTimestamp(String fieldName) throws IgniteObjectException {
 +        return readTimestamp(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Timestamp readTimestamp() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(TIMESTAMP) == Flag.NULL)
 +            return null;
 +
-         if (flag != TIMESTAMP)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadTimestamp(true);
++        return doReadTimestamp();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override public <T> T readObject(String fieldName) throws IgniteObjectException {
 +        return (T)readObject(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object readObject() throws IgniteObjectException {
-         return doReadObject(true);
++        return doReadObject();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Object readObjectDetached() throws IgniteObjectException {
-         return unmarshal(true, true);
++        return unmarshal(true);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public byte[] readByteArray(String fieldName) throws IgniteObjectException {
 +        return readByteArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public byte[] readByteArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(BYTE_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != BYTE_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadByteArray(true);
++        return doReadByteArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public short[] readShortArray(String fieldName) throws IgniteObjectException {
 +        return readShortArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public short[] readShortArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(SHORT_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != SHORT_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadShortArray(true);
++        return doReadShortArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public int[] readIntArray(String fieldName) throws IgniteObjectException {
 +        return readIntArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public int[] readIntArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(INT_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != INT_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadIntArray(true);
++        return doReadIntArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public long[] readLongArray(String fieldName) throws IgniteObjectException {
 +        return readLongArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public long[] readLongArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(LONG_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != LONG_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadLongArray(true);
++        return doReadLongArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public float[] readFloatArray(String fieldName) throws IgniteObjectException {
 +        return readFloatArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public float[] readFloatArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(FLOAT_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != FLOAT_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadFloatArray(true);
++        return doReadFloatArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public double[] readDoubleArray(String fieldName) throws IgniteObjectException {
 +        return readDoubleArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public double[] readDoubleArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(DOUBLE_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != DOUBLE_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadDoubleArray(true);
++        return doReadDoubleArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public char[] readCharArray(String fieldName) throws IgniteObjectException {
 +        return readCharArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public char[] readCharArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(CHAR_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != CHAR_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadCharArray(true);
++        return doReadCharArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public boolean[] readBooleanArray(String fieldName) throws IgniteObjectException {
 +        return readBooleanArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public boolean[] readBooleanArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(BOOLEAN_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != BOOLEAN_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadBooleanArray(true);
++        return doReadBooleanArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override @Nullable public BigDecimal[] readDecimalArray(String fieldName) throws IgniteObjectException {
 +        return readDecimalArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override @Nullable public BigDecimal[] readDecimalArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(DECIMAL_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != DECIMAL_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadDecimalArray(true);
++        return doReadDecimalArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public String[] readStringArray(String fieldName) throws IgniteObjectException {
 +        return readStringArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public String[] readStringArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(STRING_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != STRING_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadStringArray(true);
++        return doReadStringArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public UUID[] readUuidArray(String fieldName) throws IgniteObjectException {
 +        return readUuidArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public UUID[] readUuidArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(UUID_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != UUID_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadUuidArray(true);
++        return doReadUuidArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Date[] readDateArray(String fieldName) throws IgniteObjectException {
 +        return readDateArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Timestamp[] readTimestampArray(String fieldName) throws IgniteObjectException {
 +        return readTimestampArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Date[] readDateArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(DATE_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != DATE_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadDateArray(true);
++        return doReadDateArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Timestamp[] readTimestampArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(TIMESTAMP_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != TIMESTAMP_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadTimestampArray(true);
++        return doReadTimestampArray();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Object[] readObjectArray(String fieldName) throws IgniteObjectException {
 +        return readObjectArray(fieldId(fieldName));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public Object[] readObjectArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(OBJ_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != OBJ_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return doReadObjectArray(true, true);
++        return doReadObjectArray(true);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T> Collection<T> readCollection(String fieldName) throws IgniteObjectException {
 +        return readCollection(fieldId(fieldName), null);
 +    }
 +
 +    /** {@inheritDoc} */
-     @Nullable @Override public <T> Collection<T> readCollection() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++    @Nullable @Override public <T> Collection<T> readCollection() throws PortableException {
++        if (checkFlag(COL) == Flag.NULL)
 +            return null;
 +
-         if (flag != COL)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return (Collection<T>)doReadCollection(true, true, null);
++        return (Collection<T>)doReadCollection(true, null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T> Collection<T> readCollection(String fieldName,
 +        Class<? extends Collection<T>> colCls) throws IgniteObjectException {
 +        return readCollection(fieldId(fieldName), colCls);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T> Collection<T> readCollection(Class<? extends Collection<T>> colCls)
 +        throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(COL) == Flag.NULL)
 +            return null;
 +
-         if (flag != COL)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return (Collection<T>)doReadCollection(true, true, colCls);
++        return (Collection<T>)doReadCollection(true, colCls);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName) throws IgniteObjectException {
 +        return (Map<K, V>)readMap(fieldId(fieldName), null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <K, V> Map<K, V> readMap() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(MAP) == Flag.NULL)
 +            return null;
 +
-         if (flag != MAP)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return (Map<K, V>)doReadMap(true, true, null);
++        return (Map<K, V>)doReadMap(true, null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName, Class<? extends Map<K, V>> mapCls)
 +        throws IgniteObjectException {
 +        return (Map<K, V>)readMap(fieldId(fieldName), mapCls);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <K, V> Map<K, V> readMap(Class<? extends Map<K, V>> mapCls)
 +        throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(MAP) == Flag.NULL)
 +            return null;
 +
-         if (flag != MAP)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         return (Map<K, V>)doReadMap(true, true, mapCls);
++        return (Map<K, V>)doReadMap(true, mapCls);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T extends Enum<?>> T readEnum(String fieldName)
 +        throws IgniteObjectException {
 +        return (T)readEnum(fieldId(fieldName), null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T extends Enum<?>> T readEnum() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(ENUM) == Flag.NULL)
 +            return null;
 +
-         if (flag != ENUM)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
- 
-         Class cls = doReadClass(true);
++        Class cls = doReadClass();
 +
-         return (T)doReadEnum(true, cls);
++        return (T)doReadEnum(cls);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T extends Enum<?>> T[] readEnumArray(String fieldName)
 +        throws IgniteObjectException {
 +        return (T[])readEnumArray(fieldId(fieldName), null);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public <T extends Enum<?>> T[] readEnumArray() throws IgniteObjectException {
-         byte flag = doReadByte(true);
- 
-         if (flag == NULL)
++        if (checkFlag(ENUM_ARR) == Flag.NULL)
 +            return null;
 +
-         if (flag != ENUM_ARR)
-             throw new IgniteObjectException("Invalid flag value: " + flag);
++        Class cls = doReadClass();
 +
-         Class cls = doReadClass(true);
++        return (T[])doReadEnumArray(cls);
++    }
++
++    /**
++     * Ensure that type flag is either null or contains expected value.
++     *
++     * @param expFlag Expected value.
++     * @return Flag.
++     * @throws IgniteObjectException If flag is neither null, nor expected.
++     */
++    private Flag checkFlag(byte expFlag) {
++        byte flag = in.readByte();
++
++        if (flag == NULL)
++            return Flag.NULL;
++        else if (flag == HANDLE)
++            return Flag.HANDLE;
++        else if (flag != expFlag) {
++            int pos = in.position() - 1;
++
++            throw new IgniteObjectException("Unexpected flag value [pos=" + pos + ", expected=" + expFlag +
++                ", actual=" + flag + ']');
++        }
 +
-         return (T[])doReadEnumArray(true, cls);
++        return Flag.NORMAL;
 +    }
 +
 +    /**
 +     * @param fieldName Field name.
-      * @return {@code true} if field is set.
++     * @return {@code True} if field is set.
 +     */
 +    public boolean hasField(String fieldName) {
-         return fieldOffset(fieldId(fieldName)) != -1;
++        return hasField(fieldId(fieldName));
++    }
++
++    /**
++     * @param fieldId Field ID.
++     * @return {@code True} if field is set.
++     */
++    private boolean hasField(int fieldId) {
++        return fieldOffset(fieldId) != 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObjectRawReader rawReader() {
-         return this;
-     }
++        in.position(rawOff);
 +
-     /**
-      * @param raw Raw flag.
-      * @return Unmarshalled value.
-      * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
-      */
-     @Nullable private Object unmarshal(boolean raw) throws IgniteObjectException {
-         return unmarshal(raw, false);
++        return this;
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Unmarshalled value.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
-     @Nullable private Object unmarshal(boolean raw, boolean detach) throws IgniteObjectException {
-         int start = raw ? rawOff : off;
++    @Nullable private Object unmarshal(boolean detach) throws IgniteObjectException {
++        int start = in.position();
 +
-         byte flag = doReadByte(raw);
++        byte flag = in.readByte();
 +
 +        switch (flag) {
 +            case NULL:
 +                return null;
 +
 +            case HANDLE:
-                 int handle = start - doReadInt(raw);
++                int handle = start - in.readInt();
 +
 +                IgniteObject handledPo = rCtx.getPortableByHandle(handle);
 +
 +                if (handledPo != null)
 +                    return handledPo;
 +
-                 off = handle;
++                in.position(handle);
 +
-                 return unmarshal(false);
++                return unmarshal();
 +
 +            case OBJ:
-                 PortableUtils.checkProtocolVersion(doReadByte(raw));
++                PortableUtils.checkProtocolVersion(in.readByte());
 +
 +                IgniteObjectEx po;
 +
 +                if (detach) {
 +                    in.position(start + GridPortableMarshaller.TOTAL_LEN_POS);
 +
 +                    int len = in.readInt();
 +
 +                    in.position(start);
 +
 +                    po = new IgniteObjectImpl(ctx, in.readByteArray(len), 0);
 +                }
 +                else
 +                    po = in.offheapPointer() > 0
 +                        ? new IgniteObjectOffheapImpl(ctx, in.offheapPointer(), start,
 +                        in.remaining() + in.position())
 +                        : new IgniteObjectImpl(ctx, in.array(), start);
 +
 +                rCtx.setPortableHandler(start, po);
 +
-                 if (raw)
-                     rawOff = start + po.length();
-                 else
-                     off = start + po.length();
++                in.position(start + po.length());
 +
 +                return po;
 +
 +            case BYTE:
-                 return doReadByte(raw);
++                return in.readByte();
 +
 +            case SHORT:
-                 return doReadShort(raw);
++                return in.readShort();
 +
 +            case INT:
-                 return doReadInt(raw);
++                return in.readInt();
 +
 +            case LONG:
-                 return doReadLong(raw);
++                return in.readLong();
 +
 +            case FLOAT:
-                 return doReadFloat(raw);
++                return in.readFloat();
 +
 +            case DOUBLE:
-                 return doReadDouble(raw);
++                return in.readDouble();
 +
 +            case CHAR:
-                 return doReadChar(raw);
++                return in.readChar();
 +
 +            case BOOLEAN:
-                 return doReadBoolean(raw);
++                return in.readBoolean();
 +
 +            case DECIMAL:
-                 return doReadDecimal(raw);
++                return doReadDecimal();
 +
 +            case STRING:
-                 return doReadString(raw);
++                return doReadString();
 +
 +            case UUID:
-                 return doReadUuid(raw);
++                return doReadUuid();
 +
 +            case DATE:
-                 return doReadDate(raw);
++                return doReadDate();
 +
 +            case TIMESTAMP:
-                 return doReadTimestamp(raw);
++                return doReadTimestamp();
 +
 +            case BYTE_ARR:
-                 return doReadByteArray(raw);
++                return doReadByteArray();
 +
 +            case SHORT_ARR:
-                 return doReadShortArray(raw);
++                return doReadShortArray();
 +
 +            case INT_ARR:
-                 return doReadIntArray(raw);
++                return doReadIntArray();
 +
 +            case LONG_ARR:
-                 return doReadLongArray(raw);
++                return doReadLongArray();
 +
 +            case FLOAT_ARR:
-                 return doReadFloatArray(raw);
++                return doReadFloatArray();
 +
 +            case DOUBLE_ARR:
-                 return doReadDoubleArray(raw);
++                return doReadDoubleArray();
 +
 +            case CHAR_ARR:
-                 return doReadCharArray(raw);
++                return doReadCharArray();
 +
 +            case BOOLEAN_ARR:
-                 return doReadBooleanArray(raw);
++                return doReadBooleanArray();
 +
 +            case DECIMAL_ARR:
-                 return doReadDecimalArray(raw);
++                return doReadDecimalArray();
 +
 +            case STRING_ARR:
-                 return doReadStringArray(raw);
++                return doReadStringArray();
 +
 +            case UUID_ARR:
-                 return doReadUuidArray(raw);
++                return doReadUuidArray();
 +
 +            case DATE_ARR:
-                 return doReadDateArray(raw);
++                return doReadDateArray();
 +
 +            case TIMESTAMP_ARR:
-                 return doReadTimestampArray(raw);
++                return doReadTimestampArray();
 +
 +            case OBJ_ARR:
-                 return doReadObjectArray(raw, false);
++                return doReadObjectArray(false);
 +
 +            case COL:
-                 return doReadCollection(raw, false, null);
++                return doReadCollection(false, null);
 +
 +            case MAP:
-                 return doReadMap(raw, false, null);
++                return doReadMap(false, null);
 +
 +            case MAP_ENTRY:
-                 return doReadMapEntry(raw, false);
++                return doReadMapEntry(false);
 +
 +            case PORTABLE_OBJ:
-                 return doReadPortableObject(raw);
++                return doReadPortableObject();
 +
 +            case ENUM:
-                 return doReadEnum(raw, doReadClass(raw));
++                return doReadEnum(doReadClass());
 +
 +            case ENUM_ARR:
-                 return doReadEnumArray(raw, doReadClass(raw));
++                return doReadEnumArray(doReadClass());
 +
 +            case CLASS:
-                 return doReadInt(raw);
++                return in.readInt();
 +
 +            case OPTM_MARSH:
-                 int len = doReadInt(true);
++                int len = in.readInt();
 +
 +                ByteArrayInputStream input = new ByteArrayInputStream(in.array(), in.position(), len);
 +
 +                Object obj;
 +
 +                try {
 +                    obj = ctx.optimizedMarsh().unmarshal(input, null);
 +                }
 +                catch (IgniteCheckedException e) {
 +                    throw new IgniteObjectException("Failed to unmarshal object with optmMarsh marshaller", e);
 +                }
 +
-                 if (raw)
-                     rawOff += len;
-                 else
-                     off += len;
- 
 +                return obj;
 +
 +            default:
 +                throw new IgniteObjectException("Invalid flag value: " + flag);
 +        }
 +    }
 +
 +    /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private byte doReadByte(boolean raw) {
-         in.position(raw ? rawOff++ : off++);
- 
-         return in.readByte();
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private short doReadShort(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         short val = in.readShort();
- 
-         if (raw)
-             rawOff += 2;
-         else
-             off += 2;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private int doReadInt(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         int val = in.readInt();
- 
-         if (raw)
-             rawOff += 4;
-         else
-             off += 4;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private long doReadLong(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         long val = in.readLong();
- 
-         if (raw)
-             rawOff += 8;
-         else
-             off += 8;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private float doReadFloat(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         float val = in.readFloat();
- 
-         if (raw)
-             rawOff += 4;
-         else
-             off += 4;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private double doReadDouble(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         double val = in.readDouble();
- 
-         if (raw)
-             rawOff += 8;
-         else
-             off += 8;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private char doReadChar(boolean raw) {
-         in.position(raw ? rawOff : off);
- 
-         char val = in.readChar();
- 
-         if (raw)
-             rawOff += 2;
-         else
-             off += 2;
- 
-         return val;
-     }
- 
-     /**
-      * @param raw Raw flag.
-      * @return Value.
-      */
-     private boolean doReadBoolean(boolean raw) {
-         in.position(raw ? rawOff++ : off++);
- 
-         return in.readBoolean();
-     }
- 
-     /**
-      * @param raw Raw flag.
 +     * @return Value.
 +     */
-     private BigDecimal doReadDecimal(boolean raw) {
-         int scale = doReadInt(raw);
-         byte[] mag = doReadByteArray(raw);
++    private BigDecimal doReadDecimal() {
++        int scale = in.readInt();
++        byte[] mag = doReadByteArray();
 +
 +        BigInteger intVal = new BigInteger(mag);
 +
 +        if (scale < 0) {
 +            scale &= 0x7FFFFFFF;
 +
 +            intVal = intVal.negate();
 +        }
 +
 +        return new BigDecimal(intVal, scale);
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Value.
 +     */
-     private String doReadString(boolean raw) {
-         if (doReadBoolean(raw)) {
++    private String doReadString() {
++        if (in.readBoolean()) {
 +            if (!in.hasArray())
-                 return new String(doReadByteArray(raw), UTF_8);
++                return new String(doReadByteArray(), UTF_8);
 +
-             int strLen = doReadInt(raw);
-             int strOff = raw ? rawOff : off;
++            int strLen = in.readInt();
++            int strOff = in.position();
 +
 +            String res = new String(in.array(), strOff, strLen, UTF_8);
 +
-             if (raw)
-                 rawOff += strLen;
-             else
-                 off += strLen;
++            in.position(in.position() + strLen);
 +
 +            return res;
 +        }
 +        else
-             return String.valueOf(doReadCharArray(raw));
++            return String.valueOf(doReadCharArray());
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Value.
 +     */
-     private UUID doReadUuid(boolean raw) {
-         return new UUID(doReadLong(raw), doReadLong(raw));
++    private UUID doReadUuid() {
++        return new UUID(in.readLong(), in.readLong());
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Value.
 +     */
-     private Date doReadDate(boolean raw) {
-         long time = doReadLong(raw);
++    private Date doReadDate() {
++        long time = in.readLong();
 +
 +        return new Date(time);
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Value.
 +     */
-     private Timestamp doReadTimestamp(boolean raw) {
-         long time = doReadLong(raw);
-         int nanos = doReadInt(raw);
++    private Timestamp doReadTimestamp() {
++        long time = in.readLong();
++        int nanos = in.readInt();
 +
 +        Timestamp ts = new Timestamp(time);
 +
 +        ts.setNanos(ts.getNanos() + nanos);
 +
 +        return ts;
 +    }
 +
 +    /**
-      * @param raw Raw flag.
 +     * @return Object.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
 +     */
-     @Nullable private Object doReadObject(boolean raw) throws IgniteObjectException {
-         IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, in, raw ? rawOff : off, ldr, rCtx);
- 
-         Object obj = reader.deserialize();
- 
-         if (raw)
-             rawOff += reader.len;
-         else
-             off += reader.len;
++    @Nullable private Object doReadObject() throws IgniteObjectException {
++        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, in, in.position(), ldr, rCtx);
 +
-         return obj;
++        return reader.deserialize();
 +    }
 +
 +    /**
 +     * @return Deserialized object.
 +     * @throws org.apache.ignite.igniteobject.IgniteObjectException If failed.
 +     */
 +    @Nullable Object deserialize() throws IgniteObjectException {
 +        Object obj;
 +
-         byte flag = doReadByte(true);
++        byte flag = in.readByte();
 +
 +        switch (flag) {
 +            case NULL:
 +                obj = null;
 +
 +                break;
 +
 +            case HANDLE:
-                 int handle = start - doReadInt(true);
++                int handle = start - in.readInt();
 +
 +                obj = rCtx.getObjectByHandle(handle);
 +
 +                if (obj == null) {
-                     off = handle;
++                    int retPos = in.position();
++
++                    in.position(handle);
 +
-                     obj = doReadObject(false);
++                    obj = doReadObject();
++
++                    in.position(retPos);
 +                }
 +
 +                break;
 +
 +            case OBJ:
-                 if (typeId == null)
-                     readObjectTypeId(true);
++                parseHeaderIfNeeded();
 +
 +                assert typeId != UNREGISTERED_TYPE_ID;
 +
-                 PortableUtils.checkProtocolVersion(doReadByte(true));
++                PortableUtils.checkProtocolVersion(in.readByte());
 +
-                 boolean userType = doReadBoolean(true);
++                boolean userType = PortableUtils.isUserType(this.readShort());
 +
 +                // Skip typeId and hash code.
-                 rawOff += 8;
++                in.position(in.position() + 8);
 +
 +                desc = ctx.descriptorForTypeId(userType, typeId, ldr);
 +
-                 len = doReadInt(true);
++                int len = in.readInt();
 +
-                 rawOff = start + doReadInt(true);
++                in.position(start + hdrLen);
 +
 +                if (desc == null)
 +                    throw new IgniteObjectInvalidClassException("Unknown type ID: " + typeId);
 +
 +                obj = desc.read(this);
 +
++                in.position(start + len);
++
 +                break;
 +
 +            case BYTE:
-                 obj = doReadByte(true);
++                obj = in.readByte();
 +
 +                break;
 +
 +            case SHORT:
-                 obj = doReadShort(true);
++                obj = in.readShort();
 +
 +                break;
 +
 +            case INT:
-                 obj = doReadInt(true);
++                obj = in.readInt();
 +
 +                break;
 +
 +            case LONG:
-                 obj = doReadLong(true);
++                obj = in.readLong();
 +
 +                break;
 +
 +            case FLOAT:
-                 obj = doReadFloat(true);
++                obj = in.readFloat();
 +
 +                break;
 +
 +            case DOUBLE:
-                 obj = doReadDouble(true);
++                obj = in.readDouble();
 +
 +                break;
 +
 +            case CHAR:
-                 obj = doReadChar(true);
++                obj = in.readChar();
 +
 +                break;
 +
 +            case BOOLEAN:
-                 obj = doReadBoolean(true);
++                obj = in.readBoolean();
 +
 +                break;
 +
 +            case DECIMAL:
-                 obj = doReadDecimal(true);
++                obj = doReadDecimal();
 +
 +                break;
 +
 +            case STRING:
-                 obj = doReadString(true);
++                obj = doReadString();
 +
 +                break;
 +
 +            case UUID:
-                 obj = doReadUuid(true);
++                obj = doReadUuid();
 +
 +                break;
 +
 +            case DATE:
-                 obj = doReadDate(true);
++                obj = doReadDate();
 +
 +                break;
 +
 +            case TIMESTAMP:
-                 obj = doReadTimestamp(true);
++                obj = doReadTimestamp();
 +
 +                break;
 +
 +            case BYTE_ARR:
-                 obj = doReadByteArray(true);
++                obj = doReadByteArray();
 +
 +                break;
 +
 +            case SHORT_ARR:
-                 obj = doReadShortArray(true);
++                obj = doReadShortArray();
 +
 +                break;
 +
 +            case INT_ARR:
-                 obj = doReadIntArray(true);
++                obj = doReadIntArray();
 +
 +                break;
 +
 +            case LONG_ARR:
-                 obj = doReadLongArray(true);
++                obj = doReadLongArray();
 +
 +                break;
 +
 +            case FLOAT_ARR:
-                 obj = doReadFloatArray(true);
++                obj = doReadFloatArray();
 +
 +                break;
 +
 +            case DOUBLE_ARR:
-                 obj = doReadDoubleArray(true);
++                obj = doReadDoubleArray();
 +
 +                break;
 +
 +            case CHAR_ARR:
-                 obj = doReadCharArray(true);
++                obj = doReadCharArray();
 +
 +                break;
 +
 +            case BOOLEAN_ARR:
-                 obj = doReadBooleanArray(true);
++                obj = doReadBooleanArray();
 +
 +                break;
 +
 +            case DECIMAL_ARR:
-                 obj = doReadDecimalArray(true);
++                obj = doReadDecimalArray();
 +
 +                break;
 +
 +            case STRING_ARR:
-                 obj = doReadStringArray(true);
++                obj = doReadStringArray();
 +
 +                break;
 +
 +            case UUID_ARR:
-                 obj = doReadUuidArray(true);
++                obj = doReadUuidArray();
 +
 +                break;
 +
 +            case DATE_ARR:
-                 obj = doReadDateArray(true);
++                obj = doReadDateArray();
 +
 +                break;
 +
 +            case TIMESTAMP_ARR:
-                 obj = doReadTimestamp

<TRUNCATED>