You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/11/02 17:36:59 UTC

[16/33] ignite git commit: IGNITE-1770: Implemented constant-time field lookup on protocol level.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
index 2b29e4d..ec7110f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
@@ -714,36 +714,13 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
-    public void testInvalidClass() throws Exception {
-        byte[] arr = new byte[20];
-
-        arr[0] = 103;
-        arr[1] = 1;
-
-        U.intToBytes(Integer.reverseBytes(11111), arr, 3);
-
-        final PortableObject po = new PortableObjectImpl(initPortableContext(new PortableMarshaller()), arr, 0);
-
-        GridTestUtils.assertThrows(log, new Callable<Object>() {
-                                       @Override public Object call() throws Exception {
-                                           po.deserialize();
-
-                                           return null;
-                                       }
-                                   }, PortableInvalidClassException.class, "Unknown type ID: 11111"
-        );
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
     public void testClassWithoutPublicConstructor() throws Exception {
         PortableMarshaller marsh = new PortableMarshaller();
 
         marsh.setTypeConfigurations(Arrays.asList(
-                                        new PortableTypeConfiguration(NoPublicConstructor.class.getName()),
-                                        new PortableTypeConfiguration(NoPublicDefaultConstructor.class.getName()),
-                                        new PortableTypeConfiguration(ProtectedConstructor.class.getName()))
+                new PortableTypeConfiguration(NoPublicConstructor.class.getName()),
+                new PortableTypeConfiguration(NoPublicDefaultConstructor.class.getName()),
+                new PortableTypeConfiguration(ProtectedConstructor.class.getName()))
         );
 
         initPortableContext(marsh);
@@ -846,11 +823,11 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
 
         CustomMappedObject1 obj1 = new CustomMappedObject1(10, "str");
 
-        PortableObject po1 = marshal(obj1, marsh);
+        PortableObjectEx po1 = marshal(obj1, marsh);
 
         assertEquals(11111, po1.typeId());
-        assertEquals(22222, intFromPortable(po1, 19));
-        assertEquals(33333, intFromPortable(po1, 32));
+        assertEquals(10, po1.field(22222));
+        assertEquals("str", po1.field(33333));
 
         assertEquals(10, po1.<CustomMappedObject1>deserialize().val1);
         assertEquals("str", po1.<CustomMappedObject1>deserialize().val2);
@@ -905,22 +882,22 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
 
         CustomMappedObject1 obj1 = new CustomMappedObject1(10, "str1");
 
-        PortableObject po1 = marshal(obj1, marsh);
+        PortableObjectEx po1 = marshal(obj1, marsh);
 
         assertEquals(11111, po1.typeId());
-        assertEquals(22222, intFromPortable(po1, 19));
-        assertEquals(33333, intFromPortable(po1, 32));
+        assertEquals(10, po1.field(22222));
+        assertEquals("str1", po1.field(33333));
 
         assertEquals(10, po1.<CustomMappedObject1>deserialize().val1);
         assertEquals("str1", po1.<CustomMappedObject1>deserialize().val2);
 
         CustomMappedObject2 obj2 = new CustomMappedObject2(20, "str2");
 
-        PortableObject po2 = marshal(obj2, marsh);
+        PortableObjectEx po2 = marshal(obj2, marsh);
 
         assertEquals(44444, po2.typeId());
-        assertEquals(55555, intFromPortable(po2, 19));
-        assertEquals(66666, intFromPortable(po2, 32));
+        assertEquals(20, po2.field(55555));
+        assertEquals("str2", po2.field(66666));
 
         assertEquals(20, po2.<CustomMappedObject2>deserialize().val1);
         assertEquals("str2", po2.<CustomMappedObject2>deserialize().val2);
@@ -1272,9 +1249,9 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         });
 
         marsh.setTypeConfigurations(Arrays.asList(new PortableTypeConfiguration(Key.class.getName()),
-                                                  new PortableTypeConfiguration("NonExistentClass2"),
-                                                  customType1,
-                                                  customType2));
+            new PortableTypeConfiguration("NonExistentClass2"),
+            customType1,
+            customType2));
 
         PortableContext ctx = initPortableContext(marsh);
 
@@ -2100,7 +2077,7 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         // Checking the writer directly.
         assertEquals(false, THREAD_LOCAL_ALLOC.isThreadLocalArrayAcquired());
 
-        try (PortableWriterExImpl writer = new PortableWriterExImpl(initPortableContext(new PortableMarshaller()), 0)) {
+        try (PortableWriterExImpl writer = new PortableWriterExImpl(initPortableContext(new PortableMarshaller()))) {
             assertEquals(true, THREAD_LOCAL_ALLOC.isThreadLocalArrayAcquired());
 
             writer.writeString("Thread local test");

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
index 1b7c319..baeb9e7 100644
--- a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
+++ b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
@@ -41,9 +41,9 @@ void CheckPrimitive(T val)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
     try
@@ -59,13 +59,18 @@ void CheckPrimitive(T val)
 
     Write<T>(writer, "test", val);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
 
-    in.Position(19);
+    in.Synchronize();
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8;
 
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
     try
@@ -79,9 +84,16 @@ void CheckPrimitive(T val)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
-    T readVal = Read<T>(reader, "test");
-    
-    BOOST_REQUIRE(readVal == val);
+    try
+    {
+        T readVal = Read<T>(reader, "test"); 
+
+        BOOST_REQUIRE(readVal == val);
+    }
+    catch (IgniteError& err)
+    {
+        BOOST_FAIL(err.GetText());
+    }
 }
 
 template<typename T>
@@ -94,14 +106,10 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
-    
-    InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
-    PortableReader reader(&readerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     try
     {
@@ -118,120 +126,172 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
     {
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
-    
-    // 1. Write NULL and see what happens.
-    WriteArray<T>(writer, fieldName, NULL, 0);
-
-    out.Synchronize();
-    in.Synchronize();
-    
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == -1);
-
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == -1);
 
     T arr1[2];
     arr1[0] = dflt;
     arr1[1] = dflt;
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == -1);
-
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
-
-    // 2. Write empty array.
     T arr2[2];
     arr2[0] = val1;
     arr2[1] = val2;
 
-    out.Position(19);
-    
-    WriteArray<T>(writer, fieldName, arr2, 0);
+    {
+        // 1. Write NULL and see what happens.
+        WriteArray<T>(writer, fieldName, NULL, 0);
 
-    out.Synchronize();
-    in.Synchronize();
+        writerImpl.PostWrite();
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 0);
+        out.Synchronize();
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 0);
+        InteropInputStream in(&mem);
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 0);
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
+        in.Synchronize();
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 0);
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
+        int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+        int32_t footerEnd = footerBegin + 8;
 
-    // 3. Partial array write.
-    out.Position(19);
-    
-    WriteArray<T>(writer, fieldName, arr2, 1);
+        PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+        PortableReader reader(&readerImpl);
 
-    out.Synchronize();
-    in.Synchronize();
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == -1);
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 1);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 1);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 1);
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
-
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == 1);
-    BOOST_REQUIRE(arr1[0] == val1);
-    BOOST_REQUIRE(arr1[1] == dflt);
-    arr1[0] = dflt;
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == -1);
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 1);
-    BOOST_REQUIRE(arr1[0] == val1);
-    BOOST_REQUIRE(arr1[1] == dflt);
-    arr1[0] = dflt;
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == -1);
 
-    // 4. Full array write.
-    out.Position(19);
-    
-    WriteArray<T>(writer, fieldName, arr2, 2);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
+    }
 
-    out.Synchronize();
-    in.Synchronize();
+    {
+        // 2. Write empty array.
+        out.Position(IGNITE_DFLT_HDR_LEN);
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 2);
+        WriteArray<T>(writer, fieldName, arr2, 0);
 
-    in.Position(19);
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 2);
+        writerImpl.PostWrite();
 
-    try
-    {
-        ReadArray<T>(reader, NULL, arr1, 2);
+        out.Synchronize();
 
-        BOOST_FAIL("Not restricted.");
+        InteropInputStream in(&mem);
+
+        in.Synchronize();
+
+        int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+        int32_t footerEnd = footerBegin + 8;
+
+        PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+        PortableReader reader(&readerImpl);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 0);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 0);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 0);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 0);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
     }
-    catch (IgniteError& err)
+
     {
-        BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
+        // 3. Partial array write.
+        out.Position(IGNITE_DFLT_HDR_LEN);
+
+        WriteArray<T>(writer, fieldName, arr2, 1);
+
+        writerImpl.PostWrite();
+
+        out.Synchronize();
+
+        InteropInputStream in(&mem);
+
+        in.Synchronize();
+
+        int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+        int32_t footerEnd = footerBegin + 8;
+
+        PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+        PortableReader reader(&readerImpl);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 1);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 1);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 1);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == 1);
+        BOOST_REQUIRE(arr1[0] == val1);
+        BOOST_REQUIRE(arr1[1] == dflt);
+        arr1[0] = dflt;
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 1);
+        BOOST_REQUIRE(arr1[0] == val1);
+        BOOST_REQUIRE(arr1[1] == dflt);
+        arr1[0] = dflt;
     }
 
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 2);
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
+    {
+        // 4. Full array write.
+        out.Position(IGNITE_DFLT_HDR_LEN);
+
+        WriteArray<T>(writer, fieldName, arr2, 2);
+
+        writerImpl.PostWrite();
+
+        out.Synchronize();
+
+        InteropInputStream in(&mem);
+
+        in.Synchronize();
+
+        int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+        int32_t footerEnd = footerBegin + 8;
+
+        PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
+        PortableReader reader(&readerImpl);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 2);
+
+        in.Position(IGNITE_DFLT_HDR_LEN);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 2);
+
+        try
+        {
+            ReadArray<T>(reader, NULL, arr1, 2);
+
+            BOOST_FAIL("Not restricted.");
+        }
+        catch (IgniteError& err)
+        {
+            BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
+        }
 
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == 2);
-    BOOST_REQUIRE(arr1[0] == dflt);
-    BOOST_REQUIRE(arr1[1] == dflt);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 2);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
 
-    BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 2);
-    BOOST_REQUIRE(arr1[0] == val1);
-    BOOST_REQUIRE(arr1[1] == val2);
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == 2);
+        BOOST_REQUIRE(arr1[0] == dflt);
+        BOOST_REQUIRE(arr1[1] == dflt);
+
+        BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 2);
+        BOOST_REQUIRE(arr1[0] == val1);
+        BOOST_REQUIRE(arr1[1] == val2);
+    }
 }
 
 void CheckWritesRestricted(PortableWriter& writer)
@@ -407,10 +467,10 @@ void CheckCollectionEmpty(CollectionType* colType)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableCollectionWriter<PortableInner> colWriter = colType ?
         writer.WriteCollection<PortableInner>("field1", *colType) : writer.WriteCollection<PortableInner>("field1");
@@ -443,13 +503,19 @@ void CheckCollectionEmpty(CollectionType* colType)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -487,10 +553,10 @@ void CheckCollection(CollectionType* colType)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableCollectionWriter<PortableInner> colWriter = colType ?
         writer.WriteCollection<PortableInner>("field1", *colType) : writer.WriteCollection<PortableInner>("field1");
@@ -527,13 +593,19 @@ void CheckCollection(CollectionType* colType)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -586,10 +658,10 @@ void CheckCollectionIterators(CollectionType* colType)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     if (colType)
         writer.WriteCollection("field1", writeValues.begin(), writeValues.end(), *colType);
@@ -598,13 +670,19 @@ void CheckCollectionIterators(CollectionType* colType)
     
     writer.WriteInt8("field2", 1);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     BOOST_REQUIRE(reader.ReadCollectionSize("field1") == writeValues.size());
 
@@ -632,10 +710,10 @@ void CheckMapEmpty(MapType* mapType)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableMapWriter<int8_t, PortableInner> mapWriter = mapType ?
         writer.WriteMap<int8_t, PortableInner>("field1", *mapType) : writer.WriteMap<int8_t, PortableInner>("field1");
@@ -668,13 +746,19 @@ void CheckMapEmpty(MapType* mapType)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -715,10 +799,10 @@ void CheckMap(MapType* mapType)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableMapWriter<int8_t, PortableInner> mapWriter = mapType ?
         writer.WriteMap<int8_t, PortableInner>("field1", *mapType) : writer.WriteMap<int8_t, PortableInner>("field1");
@@ -755,13 +839,19 @@ void CheckMap(MapType* mapType)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -913,10 +1003,10 @@ BOOST_AUTO_TEST_CASE(TestGuidNull)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     try
     {
@@ -931,13 +1021,19 @@ BOOST_AUTO_TEST_CASE(TestGuidNull)
 
     writer.WriteNull("test");
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
     
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     try
     {
@@ -962,10 +1058,10 @@ BOOST_AUTO_TEST_CASE(TestString) {
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     const char* writeVal1 = "testtest";
     const char* writeVal2 = "test";
@@ -1010,13 +1106,19 @@ BOOST_AUTO_TEST_CASE(TestString) {
     writer.WriteString("field4", NULL);
     writer.WriteString("field5", NULL, 4);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 5;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     try
     {
@@ -1074,21 +1176,27 @@ BOOST_AUTO_TEST_CASE(TestStringArrayNull)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1130,10 +1238,10 @@ BOOST_AUTO_TEST_CASE(TestStringArrayEmpty)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableStringArrayWriter arrWriter = writer.WriteStringArray("field1");
     
@@ -1193,13 +1301,19 @@ BOOST_AUTO_TEST_CASE(TestStringArrayEmpty)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1245,10 +1359,10 @@ BOOST_AUTO_TEST_CASE(TestStringArray)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableStringArrayWriter arrWriter = writer.WriteStringArray("field1");
 
@@ -1314,13 +1428,19 @@ BOOST_AUTO_TEST_CASE(TestStringArray)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1413,22 +1533,28 @@ BOOST_AUTO_TEST_CASE(TestObject)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteObject("field1", writeVal1);
     writer.WriteObject("field2", writeVal2);
     writer.WriteNull("field3");
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 3;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN); 
 
     PortableInner readVal1 = reader.ReadObject<PortableInner>("field1");
     BOOST_REQUIRE(writeVal1.GetValue() == readVal1.GetValue());
@@ -1450,22 +1576,28 @@ BOOST_AUTO_TEST_CASE(TestNestedObject)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteObject("field1", writeVal1);
     writer.WriteObject("field2", writeVal2);
     writer.WriteNull("field3");
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 3;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableOuter readVal1 = reader.ReadObject<PortableOuter>("field1");
     BOOST_REQUIRE(writeVal1.GetValue() == readVal1.GetValue());
@@ -1487,21 +1619,27 @@ BOOST_AUTO_TEST_CASE(TestArrayNull)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1530,10 +1668,10 @@ BOOST_AUTO_TEST_CASE(TestArrayEmpty)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableArrayWriter<PortableInner> arrWriter = writer.WriteArray<PortableInner>("field1");
 
@@ -1565,13 +1703,19 @@ BOOST_AUTO_TEST_CASE(TestArrayEmpty)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1604,10 +1748,10 @@ BOOST_AUTO_TEST_CASE(TestArray)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableArrayWriter<PortableInner> arrWriter = writer.WriteArray<PortableInner>("field1");
 
@@ -1643,13 +1787,19 @@ BOOST_AUTO_TEST_CASE(TestArray)
         BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_PORTABLE);
     }
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1690,21 +1840,27 @@ BOOST_AUTO_TEST_CASE(TestCollectionNull)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -1770,21 +1926,27 @@ BOOST_AUTO_TEST_CASE(TestMapNull)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
+
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin + 8 * 2;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100, footerBegin, footerEnd);
     PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -1841,10 +2003,10 @@ BOOST_AUTO_TEST_CASE(TestRawMode)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
+    PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL, 0);
     PortableWriter writer(&writerImpl);
 
-    out.Position(19);
+    out.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableRawWriter rawWriter = writer.RawWriter();
 
@@ -1863,13 +2025,19 @@ BOOST_AUTO_TEST_CASE(TestRawMode)
 
     CheckWritesRestricted(writer);
 
+    writerImpl.PostWrite();
+
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 19);
-    PortableReader reader(&readerImpl);
 
-    in.Position(19);
+    int32_t footerBegin = in.ReadInt32(IGNITE_OFFSET_SCHEMA_OR_RAW_OFF);
+    int32_t footerEnd = footerBegin;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, footerBegin, footerBegin, footerEnd);
+    PortableReader reader(&readerImpl);
+    
+    in.Position(IGNITE_DFLT_HDR_LEN);
 
     PortableRawReader rawReader = reader.RawReader();
 
@@ -1909,13 +2077,42 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
     int32_t pos = in.Position();
     in.ReadInt8(); // We do not need a header here.
     in.ReadInt8(); // We do not need proto ver here.
-    bool usrType = in.ReadBool();
+
+    int16_t flags = in.ReadInt16();
     int32_t typeId = in.ReadInt32();
     int32_t hashCode = in.ReadInt32();
     int32_t len = in.ReadInt32();
-    int32_t rawOff = in.ReadInt32();
 
-    PortableReaderImpl readerImpl(&in, &idRslvr, pos, usrType, typeId, hashCode, len, rawOff);
+    in.ReadInt32(); // Ignoring Schema Id.
+
+    int32_t schemaOrRawOff = in.ReadInt32();
+
+    int32_t rawOff;
+    int32_t footerBegin;
+
+    if (flags & IGNITE_PORTABLE_FLAG_RAW_ONLY)
+        footerBegin = len;
+    else
+        footerBegin = schemaOrRawOff;
+
+    int32_t trailingBytes = (len - footerBegin) % 8;
+
+    int32_t footerEnd = len - trailingBytes;
+
+    if (trailingBytes)
+        rawOff = in.ReadInt32(pos + len - 4);
+    else
+        rawOff = schemaOrRawOff;
+
+    bool usrType = flags & IGNITE_PORTABLE_FLAG_USER_OBJECT;
+
+    footerBegin += pos;
+    footerEnd += pos;
+
+    PortableReaderImpl readerImpl(&in, &idRslvr, pos, usrType, 
+                                  typeId, hashCode, len, rawOff, 
+                                  footerBegin, footerEnd);
+
     PortableReader reader(&readerImpl);
 
     // 1. Clockwise.
@@ -1925,34 +2122,34 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
 
     // 2. Counter closkwise.
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     // 3. Same field twice.
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     
     // 4. Read missing field in between.
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("missing") == 0);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
 
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("missing") == 0);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     // 5. Invalid field type.
-    in.Position(19);
+    in.Position(IGNITE_DFLT_HDR_LEN);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     try

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/Makefile.am b/modules/platforms/cpp/core/Makefile.am
index db50326..4c55545 100644
--- a/modules/platforms/cpp/core/Makefile.am
+++ b/modules/platforms/cpp/core/Makefile.am
@@ -39,6 +39,7 @@ COMMON_SRC = os/linux/src/impl/utils.cpp \
              src/impl/portable/portable_utils.cpp \
              src/impl/portable/portable_reader_impl.cpp \
              src/impl/portable/portable_writer_impl.cpp \
+             src/impl/portable/portable_schema.cpp \
              src/portable/portable_containers.cpp \
              src/portable/portable_raw_reader.cpp \
              src/portable/portable_raw_writer.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/Makefile.am b/modules/platforms/cpp/core/include/Makefile.am
index b20e2f7..186e867 100644
--- a/modules/platforms/cpp/core/include/Makefile.am
+++ b/modules/platforms/cpp/core/include/Makefile.am
@@ -46,6 +46,7 @@ nobase_include_HEADERS = ignite/cache/cache.h \
                          ignite/impl/portable/portable_reader_impl.h \
                          ignite/impl/portable/portable_utils.h \
                          ignite/impl/portable/portable_writer_impl.h \
+                         ignite/impl/portable/portable_schema.h \
                          ignite/impl/ignite_environment.h \
                          ignite/impl/ignite_impl.h \
                          ignite/impl/handle_registry.h \

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
index 850e6c3..211ac6d 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_output_stream.h
@@ -186,6 +186,14 @@ namespace ignite
                 void Position(const int32_t val);
 
                 /**
+                 * Reserve specified number of bytes in stream.
+                 *
+                 * @param num Number of bytes to reserve.
+                 * @return Absolute position to reserved space.
+                 */
+                int32_t Reserve(int32_t num);
+
+                /**
                  * Synchronize data with underlying memory.
                  */
                 void Synchronize();

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
index 9efaa28..c6dad50 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
@@ -38,14 +38,29 @@ namespace ignite
             /** Portable protocol version.  */
             const int8_t IGNITE_PROTO_VER = 1;
 
-            /** Full header length. */
-            const int32_t IGNITE_FULL_HDR_LEN = 19;
+            /** Protocol version position. */
+            const int32_t PROTO_VER_POS = 1;
+
+            /** Header offset: Flags. */
+            const int32_t IGNITE_OFFSET_FLAGS = 2;
+
+            /** Header offset: Type ID. */
+            const int32_t IGNITE_OFFSET_TYPE_ID = 4;
+
+            /** Header offset: Hash Code. */
+            const int32_t IGNITE_OFFSET_HASH_CODE = 8;
+
+            /** Header offset: Object Length. */
+            const int32_t IGNITE_OFFSET_LEN = 12;
 
-            /** Header offset: length. */
-            const int32_t IGNITE_OFFSET_LEN = 11;
+            /** Header offset: Schema ID. */
+            const int32_t IGNITE_OFFSET_SCHEMA_ID = 16;
 
-            /** Header offset: raw offset. */
-            const int32_t IGNITE_OFFSET_RAW = 15;
+            /** Header offset: Schema or Raw Offset. */
+            const int32_t IGNITE_OFFSET_SCHEMA_OR_RAW_OFF = 20;
+
+            /** Full header length. */
+            const int32_t IGNITE_DFLT_HDR_LEN = 24;
 
             /** Type: object. */
             const int8_t IGNITE_TYPE_OBJECT = IGNITE_HDR_FULL;
@@ -148,6 +163,12 @@ namespace ignite
 
             /** Read/write map. */
             const int32_t IGNITE_PORTABLE_MODE_MAP = 3;
+
+            /** User object flag. */
+            const int16_t IGNITE_PORTABLE_FLAG_USER_OBJECT = 0x0001;
+
+            /** Raw only flag. */
+            const int16_t IGNITE_PORTABLE_FLAG_RAW_ONLY = 0x0002;
         }
     }    
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
index 08b8fe1..fe25c87 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
@@ -25,7 +25,7 @@
 #include "ignite/impl/interop/interop_input_stream.h"
 #include "ignite/impl/portable/portable_common.h"
 #include "ignite/impl/portable/portable_id_resolver.h"
-#include "ignite/impl/portable/portable_utils.h"
+#include "ignite/impl/portable/portable_schema.h"
 #include "ignite/impl/utils.h"
 #include "ignite/portable/portable_consts.h"
 #include "ignite/portable/portable_type.h"
@@ -54,9 +54,12 @@ namespace ignite
                  * @param hashcode Hash code.
                  * @param len Length in bytes.
                  * @param rawOff Raw data offset.
+                 * @param footerBegin Footer beginning absolute position in stream.
+                 * @param footerEnd Footer ending absolute position in stream.
                  */
-                PortableReaderImpl(interop::InteropInputStream* stream, PortableIdResolver* idRslvr,                     
-                    int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff);
+                PortableReaderImpl(interop::InteropInputStream* stream, PortableIdResolver* idRslvr,
+                    int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff,
+                    int32_t footerBegin, int32_t footerEnd);
 
                 /**
                  * Constructor used to construct light-weight reader allowing only raw operations 
@@ -182,7 +185,7 @@ namespace ignite
                  * @return Actual amount of elements read. If "len" argument is less than actual
                  *     array size or resulting array is set to null, nothing will be written
                  *     to resulting array and returned value will contain required array length.
-                 *      -1 will be returned in case array in stream was null.
+                 *     -1 will be returned in case array in stream was null.
                  */
                 int32_t ReadInt16Array(const char* fieldName, int16_t* res, const int32_t len);
 
@@ -556,11 +559,13 @@ namespace ignite
                     CheckSingleMode(true);
 
                     int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
-                    int32_t fieldLen = SeekField(fieldId);
+                    int32_t fieldPos = FindField(fieldId);
 
-                    if (fieldLen <= 0)
+                    if (fieldPos <= 0)
                         return -1;
 
+                    stream->Position(fieldPos);
+
                     int32_t size;
                     int32_t id = StartContainerSession(false, IGNITE_TYPE_COLLECTION, &size);
 
@@ -701,13 +706,15 @@ namespace ignite
                     CheckRawMode(false);
 
                     int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName); 
-                        
-                    int32_t fieldLen = SeekField(fieldId); 
-                        
-                    if (fieldLen > 0) 
-                        return ReadTopObject<T>();
-                    
-                    return GetNull<T>();
+
+                    int32_t fieldPos = FindField(fieldId);
+
+                    if (fieldPos <= 0)
+                        return GetNull<T>();
+
+                    stream->Position(fieldPos);
+
+                    return ReadTopObject<T>();
                 }
 
                 /**
@@ -718,7 +725,7 @@ namespace ignite
                 /**
                  * Read object.
                  *
-                 * @param obj Object to write.
+                 * @return Read object.
                  */
                 template<typename T>
                 T ReadTopObject()
@@ -726,54 +733,93 @@ namespace ignite
                     int32_t pos = stream->Position();
                     int8_t hdr = stream->ReadInt8();
 
-                    if (hdr == IGNITE_HDR_NULL)
-                        return GetNull<T>();
-                    else if (hdr == IGNITE_HDR_HND) {
-                        IGNITE_ERROR_1(ignite::IgniteError::IGNITE_ERR_PORTABLE, "Circular references are not supported.");
-                    }
-                    else if (hdr == IGNITE_TYPE_PORTABLE)
+                    switch (hdr)
                     {
-                        int32_t portLen = stream->ReadInt32(); // Total length of portable object.
-                        int32_t curPos = stream->Position();
-                        int32_t portOff = stream->ReadInt32(curPos + portLen);
+                        case IGNITE_HDR_NULL:
+                        {
+                            return GetNull<T>();
+                        }
 
-                        stream->Position(curPos + portOff); // Position stream right on the object.
+                        case IGNITE_HDR_HND:
+                        {
+                            IGNITE_ERROR_1(ignite::IgniteError::IGNITE_ERR_PORTABLE, 
+                                           "Circular references are not supported.");
+                        }
 
-                        T val = ReadTopObject<T>();
+                        case IGNITE_TYPE_PORTABLE:
+                        {
+                            int32_t portLen = stream->ReadInt32(); // Total length of portable object.
+                            int32_t curPos = stream->Position();
+                            int32_t portOff = stream->ReadInt32(curPos + portLen);
 
-                        stream->Position(curPos + portLen + 4); // Position stream after portable.
+                            stream->Position(curPos + portOff); // Position stream right on the object.
 
-                        return val;
-                    }
-                    else
-                    {
-                        if (hdr != IGNITE_HDR_FULL) {
-                            IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, "Unexpected header during deserialization: ", hdr);
+                            T val = ReadTopObject<T>();
+
+                            stream->Position(curPos + portLen + 4); // Position stream after portable.
+
+                            return val;
                         }
-                        else {
+
+                        case IGNITE_HDR_FULL:
+                        {
                             int8_t protoVer = stream->ReadInt8();
 
                             if (protoVer != IGNITE_PROTO_VER) {
-                                IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, "Unsupported portable protocol version: ", protoVer);
+                                IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, 
+                                               "Unsupported portable protocol version: ", protoVer);
                             }
-                            else {
-                                bool usrType = stream->ReadBool();
-                                int32_t typeId = stream->ReadInt32();
-                                int32_t hashCode = stream->ReadInt32();
-                                int32_t len = stream->ReadInt32();
-                                int32_t rawOff = stream->ReadInt32();
 
-                                ignite::portable::PortableType<T> type;
-                                TemplatedPortableIdResolver<T> idRslvr(type);
-                                PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType, typeId, hashCode, len, rawOff);
-                                ignite::portable::PortableReader reader(&readerImpl);
+                            int16_t flags = stream->ReadInt16();
+                            int32_t typeId = stream->ReadInt32();
+                            int32_t hashCode = stream->ReadInt32();
+                            int32_t len = stream->ReadInt32();
 
-                                T val = type.Read(reader);
+                            // Ignoring Schema Id for now.
+                            stream->ReadInt32();
 
-                                stream->Position(pos + len);
+                            int32_t schemaOrRawOff = stream->ReadInt32();
 
-                                return val;
-                            }
+                            int32_t rawOff;
+                            int32_t footerBegin;
+
+                            if (flags & IGNITE_PORTABLE_FLAG_RAW_ONLY)
+                                footerBegin = len;
+                            else
+                                footerBegin = schemaOrRawOff;
+
+                            int32_t trailingBytes = (len - footerBegin) % 8;
+
+                            int32_t footerEnd = len - trailingBytes;
+
+                            if (trailingBytes)
+                                rawOff = stream->ReadInt32(pos + len - 4);
+                            else
+                                rawOff = schemaOrRawOff;
+
+                            bool usrType = flags & IGNITE_PORTABLE_FLAG_USER_OBJECT;
+
+                            footerBegin += pos;
+                            footerEnd += pos;
+
+                            ignite::portable::PortableType<T> type;
+                            TemplatedPortableIdResolver<T> idRslvr(type);
+                            PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType,
+                                                          typeId, hashCode, len, rawOff,
+                                                          footerBegin, footerEnd);
+                            ignite::portable::PortableReader reader(&readerImpl);
+
+                            T val = type.Read(reader);
+
+                            stream->Position(pos + len);
+
+                            return val;
+                        }
+
+                        default:
+                        {
+                            IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, 
+                                           "Unexpected header during deserialization: ", hdr);
                         }
                     }
                 }
@@ -797,46 +843,52 @@ namespace ignite
                 impl::interop::InteropInputStream* GetStream();
             private:
                 /** Underlying stream. */
-                interop::InteropInputStream* stream;   
-                
+                interop::InteropInputStream* stream;
+
                 /** ID resolver. */
-                PortableIdResolver* idRslvr;           
+                PortableIdResolver* idRslvr;
 
                 /** Position in the stream where this object starts. */
-                int32_t pos;       
-                
+                int32_t pos;
+
                 /** Whether this is user type or system type. */
-                bool usrType;      
-                
+                bool usrType;
+
                 /** Type ID as defined in the stream. */
-                int32_t typeId;    
-                
+                int32_t typeId;
+
                 /** Hash code. */
-                int32_t hashCode;  
-                
+                int32_t hashCode;
+
                 /** Total object length in the stream. */
-                int32_t len;       
-                
+                int32_t len;
+
                 /** Raw data offset. */
-                int32_t rawOff;    
+                int32_t rawOff;
 
                 /** Raw mode flag. */
-                bool rawMode;      
+                bool rawMode;
 
                 /** Elements read session ID generator. */
-                int32_t elemIdGen; 
-                
+                int32_t elemIdGen;
+
                 /** Elements read session ID. */
-                int32_t elemId;    
-                
+                int32_t elemId;
+
                 /** Total amount of elements in collection. */
-                int32_t elemCnt;   
-                
+                int32_t elemCnt;
+
                 /** Amount of elements read. */
-                int32_t elemRead;  
+                int32_t elemRead;
 
-                IGNITE_NO_COPY_ASSIGNMENT(PortableReaderImpl)
+                /** Footer beginning position. */
+                int32_t footerBegin;
+
+                /** Footer ending position. */
+                int32_t footerEnd;
 
+                IGNITE_NO_COPY_ASSIGNMENT(PortableReaderImpl)
+                    
                 /**
                  * Internal routine to read Guid array.
                  *
@@ -892,24 +944,27 @@ namespace ignite
                         CheckSingleMode(true);
 
                         int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
-                        int32_t fieldLen = SeekField(fieldId);
+                        int32_t fieldPos = FindField(fieldId);
 
-                        if (fieldLen > 0)
-                        {
-                            int8_t typeId = stream->ReadInt8();
+                        if (fieldPos <= 0)
+                            return dflt;
 
-                            if (typeId == expHdr)
-                                return func(stream);
-                            else if (typeId != IGNITE_HDR_NULL)
-                            {
-                                int32_t pos = stream->Position();
+                        stream->Position(fieldPos);
 
-                                IGNITE_ERROR_FORMATTED_3(IgniteError::IGNITE_ERR_PORTABLE, "Invalid type ID", 
-                                    "position", pos, "expected", expHdr, "actual", typeId)
-                            }
+                        int8_t typeId = stream->ReadInt8();
+                        
+                        if (typeId == IGNITE_HDR_NULL)
+                            return dflt;
+
+                        if (typeId != expHdr)
+                        {
+                            int32_t pos = stream->Position();
+
+                            IGNITE_ERROR_FORMATTED_3(IgniteError::IGNITE_ERR_PORTABLE, "Invalid type ID", 
+                                "position", pos, "expected", static_cast<int>(expHdr), "actual", static_cast<int>(typeId))
                         }
 
-                        return dflt;
+                        return func(stream);
                     }
                 }
 
@@ -964,20 +1019,16 @@ namespace ignite
                         int32_t pos = stream->Position();
 
                         int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
-                        int32_t fieldLen = SeekField(fieldId);
+                        int32_t fieldPos = FindField(fieldId);
 
-                        if (fieldLen > 0) {
-                            int32_t realLen = ReadArrayInternal(res, len, stream, func, expHdr);
+                        if (fieldPos <= 0)
+                            return -1;
 
-                            // If actual read didn't occur return to initial position so that we do not perform 
-                            // N jumps to find the field again, where N is total amount of fields.
-                            if (realLen != -1 && (!res || realLen > len))
-                                stream->Position(pos);
+                        stream->Position(fieldPos);
 
-                            return realLen;
-                        }
+                        int32_t realLen = ReadArrayInternal(res, len, stream, func, expHdr);
 
-                        return -1;
+                        return realLen;
                     }
                 }
 
@@ -1056,7 +1107,7 @@ namespace ignite
                  * @param fieldId Field ID.
                  * @return Field length or -1 if field is not found.
                  */
-                int32_t SeekField(const int32_t fieldId);
+                int32_t FindField(const int32_t fieldId);
 
                 /**
                  * Check raw mode.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
new file mode 100644
index 0000000..1795fd1
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_schema.h
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_PORTABLE_SCHEMA
+#define _IGNITE_IMPL_PORTABLE_SCHEMA
+
+#include <vector>
+#include <stdint.h>
+
+#include <ignite/common/common.h>
+#include <ignite/impl/interop/interop_output_stream.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            /** Portable writer implementation forward declaration. */
+            class PortableWriterImpl;
+
+            /**
+             * Portable schema.
+             */
+            class IGNITE_IMPORT_EXPORT PortableSchema
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                PortableSchema();
+
+                /**
+                 * Destructor.
+                 */
+                ~PortableSchema();
+
+                /**
+                 * Add another field to schema.
+                 *
+                 * @param id Field id.
+                 * @param offset Field offset.
+                 */
+                void AddField(int32_t fieldId, int32_t offset);
+
+                /**
+                 * Write Schema to stream.
+                 *
+                 * @param out Stream to write schema to.
+                 */
+                void Write(interop::InteropOutputStream& out) const;
+
+                /**
+                 * Get Schema ID.
+                 *
+                 * @return Schema id.
+                 */
+                int32_t GetId() const
+                {
+                    return id;
+                }
+
+                /** 
+                 * Check if the schema contains field info.
+                 *
+                 * @return True if does not contain field info.
+                 */
+                bool Empty() const;
+
+                /** 
+                 * Clear schema info.
+                 */
+                void Clear();
+
+            private:
+                /**
+                * Single schema field info.
+                */
+                struct PortableSchemaFieldInfo
+                {
+                    int32_t id;
+                    int32_t offset;
+                };
+
+                /** Type alias for vector of field info. */
+                typedef std::vector<PortableSchemaFieldInfo> FieldContainer;
+
+                /** Schema ID. */
+                int32_t id;
+
+                /** Information about written fields. */
+                FieldContainer* fieldsInfo;
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableSchema)
+            };
+        }
+    }
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
index 2d94dbf..025677b 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
@@ -30,6 +30,7 @@
 #include "ignite/impl/portable/portable_id_resolver.h"
 #include "ignite/impl/portable/portable_metadata_manager.h"
 #include "ignite/impl/portable/portable_utils.h"
+#include "ignite/impl/portable/portable_schema.h"
 #include "ignite/portable/portable_consts.h"
 #include "ignite/portable/portable_type.h"
 #include "ignite/guid.h"
@@ -55,7 +56,7 @@ namespace ignite
                  * @param metaHnd Metadata handler.
                  */
                 PortableWriterImpl(ignite::impl::interop::InteropOutputStream* stream, PortableIdResolver* idRslvr, 
-                    PortableMetadataManager* metaMgr, PortableMetadataHandler* metaHnd);
+                    PortableMetadataManager* metaMgr, PortableMetadataHandler* metaHnd, int32_t start);
                 
                 /**
                  * Constructor used to construct light-weight writer allowing only raw operations 
@@ -470,7 +471,7 @@ namespace ignite
                 {
                     StartContainerSession(false);
 
-                    WriteFieldIdSkipLength(fieldName, IGNITE_TYPE_COLLECTION);
+                    WriteFieldId(fieldName, IGNITE_TYPE_COLLECTION);
 
                     WriteCollectionWithinSession(first, last, typ);
                 }
@@ -519,7 +520,7 @@ namespace ignite
                 void WriteElement(int32_t id, K key, V val)
                 {
                     CheckSession(id);
-                    
+
                     WriteTopObject<K>(key);
                     WriteTopObject<V>(val);
 
@@ -555,21 +556,11 @@ namespace ignite
                 template<typename T>
                 void WriteObject(const char* fieldName, T val)
                 {
-                    CheckRawMode(false); 
-                        
-                    // 1. Write field ID.
-                    WriteFieldId(fieldName, IGNITE_TYPE_OBJECT);
+                    CheckRawMode(false);
 
-                    // 2. Preserve space for length.
-                    int32_t lenPos = stream->Position();
-                    stream->Position(lenPos + 4);
+                    WriteFieldId(fieldName, IGNITE_TYPE_OBJECT);
 
-                    // 3. Actual write.
                     WriteTopObject(val);
-
-                    // 4. Write field length.
-                    int32_t len = stream->Position() - lenPos - 4;
-                    stream->WriteInt32(lenPos, len);
                 }
 
                 /**
@@ -599,28 +590,26 @@ namespace ignite
                         TemplatedPortableIdResolver<T> idRslvr(type);
                         ignite::common::concurrent::SharedPointer<PortableMetadataHandler> metaHnd;
 
-                        if (metaMgr)                        
+                        if (metaMgr)
                             metaHnd = metaMgr->GetHandler(idRslvr.GetTypeId());
 
-                        PortableWriterImpl writerImpl(stream, &idRslvr, metaMgr, metaHnd.Get());
-                        ignite::portable::PortableWriter writer(&writerImpl);
-
                         int32_t pos = stream->Position();
 
+                        PortableWriterImpl writerImpl(stream, &idRslvr, metaMgr, metaHnd.Get(), pos);
+                        ignite::portable::PortableWriter writer(&writerImpl);
+
                         stream->WriteInt8(IGNITE_HDR_FULL);
                         stream->WriteInt8(IGNITE_PROTO_VER);
-                        stream->WriteBool(true);
+                        stream->WriteInt16(IGNITE_PORTABLE_FLAG_USER_OBJECT);
                         stream->WriteInt32(idRslvr.GetTypeId());
                         stream->WriteInt32(type.GetHashCode(obj));
 
-                        stream->Position(pos + IGNITE_FULL_HDR_LEN);
+                        // Reserve space for the Object Lenght, Schema ID and Schema or Raw Offsett.
+                        stream->Reserve(12);
 
                         type.Write(writer, obj);
 
-                        int32_t len = stream->Position() - pos;
-
-                        stream->WriteInt32(pos + IGNITE_OFFSET_LEN, len);
-                        stream->WriteInt32(pos + IGNITE_OFFSET_RAW, writerImpl.GetRawPosition() - pos);
+                        writerImpl.PostWrite();
 
                         if (metaMgr)
                             metaMgr->SubmitHandler(type.GetTypeName(), idRslvr.GetTypeId(), metaHnd.Get());
@@ -628,6 +617,28 @@ namespace ignite
                 }
 
                 /**
+                 * Perform all nessasary post-write operations.
+                 * Includes:
+                 * - writing object length;
+                 * - writing schema offset;
+                 * - writing schema id;
+                 * - writing schema to the tail.
+                 */
+                void PostWrite();
+
+                /**
+                 * Check if the writer has object schema.
+                 *
+                 * @return True if has schema.
+                 */
+                bool HasSchema() const;
+                
+                /**
+                 * Writes contating schema and clears current schema.
+                 */
+                void WriteAndClearSchema();
+
+                /**
                  * Get underlying stream.
                  *
                  * @return Stream.
@@ -638,31 +649,37 @@ namespace ignite
                 ignite::impl::interop::InteropOutputStream* stream; 
                 
                 /** ID resolver. */
-                PortableIdResolver* idRslvr;                     
+                PortableIdResolver* idRslvr;
                 
                 /** Metadata manager. */
-                PortableMetadataManager* metaMgr;                   
+                PortableMetadataManager* metaMgr;
                 
                 /** Metadata handler. */
-                PortableMetadataHandler* metaHnd;                  
+                PortableMetadataHandler* metaHnd;
 
                 /** Type ID. */
-                int32_t typeId;                                       
+                int32_t typeId;
 
                 /** Elements write session ID generator. */
-                int32_t elemIdGen;                                   
+                int32_t elemIdGen;
                 
                 /** Elements write session ID. */
-                int32_t elemId;                                       
+                int32_t elemId;
                 
                 /** Elements count. */
-                int32_t elemCnt;                                      
+                int32_t elemCnt;
                 
                 /** Elements start position. */
-                int32_t elemPos;                                      
+                int32_t elemPos;
 
                 /** Raw data offset. */
-                int32_t rawPos;                                       
+                int32_t rawPos;
+
+                /** Schema of the current object. */
+                PortableSchema schema;
+
+                /** Writing start position. */
+                int32_t start;
 
                 IGNITE_NO_COPY_ASSIGNMENT(PortableWriterImpl)
 
@@ -736,7 +753,6 @@ namespace ignite
 
                     WriteFieldId(fieldName, typ);
 
-                    stream->WriteInt32(1 + len);
                     stream->WriteInt8(typ);
 
                     func(stream, val);
@@ -769,14 +785,12 @@ namespace ignite
 
                     if (val)
                     {
-                        stream->WriteInt32(5 + (len << lenShift));
                         stream->WriteInt8(hdr);
                         stream->WriteInt32(len);
                         func(stream, val, len);
                     }
                     else
                     {
-                        stream->WriteInt32(1);
                         stream->WriteInt8(IGNITE_HDR_NULL);
                     }
                 }
@@ -839,23 +853,6 @@ namespace ignite
                 void WriteFieldId(const char* fieldName, int32_t fieldTypeId);
 
                 /**
-                 * Write field ID and skip field length.
-                 *
-                 * @param fieldName Field name.
-                 * @param fieldTypeId Field type ID.
-                 */
-                void WriteFieldIdSkipLength(const char* fieldName, int32_t fieldTypeId);
-
-                /**
-                 * Write field ID and length.
-                 *
-                 * @param fieldName Field name.
-                 * @param fieldTypeId Field type ID.
-                 * @param len Length.
-                 */
-                void WriteFieldIdAndLength(const char* fieldName, int32_t fieldTypeId, int32_t len);
-
-                /**
                  * Write primitive value.
                  *
                  * @param obj Value.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/project/vs/core.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj b/modules/platforms/cpp/core/project/vs/core.vcxproj
index dfed87b..93ac836 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj
@@ -225,6 +225,7 @@
     <ClInclude Include="..\..\include\ignite\impl\portable\portable_metadata_updater.h" />
     <ClInclude Include="..\..\include\ignite\impl\portable\portable_metadata_updater_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\portable\portable_reader_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\portable\portable_schema.h" />
     <ClInclude Include="..\..\include\ignite\impl\portable\portable_utils.h" />
     <ClInclude Include="..\..\include\ignite\impl\portable\portable_writer_impl.h" />
     <ClInclude Include="..\..\include\ignite\portable\portable.h" />
@@ -257,6 +258,7 @@
     <ClCompile Include="..\..\src\impl\portable\portable_metadata_updater.cpp" />
     <ClCompile Include="..\..\src\impl\portable\portable_metadata_updater_impl.cpp" />
     <ClCompile Include="..\..\src\impl\portable\portable_reader_impl.cpp" />
+    <ClCompile Include="..\..\src\impl\portable\portable_schema.cpp" />
     <ClCompile Include="..\..\src\impl\portable\portable_utils.cpp" />
     <ClCompile Include="..\..\src\impl\portable\portable_writer_impl.cpp" />
     <ClCompile Include="..\..\src\portable\portable_containers.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
index 67dd455..da00df3 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
@@ -82,6 +82,9 @@
     <ClCompile Include="..\..\src\impl\portable\portable_metadata_updater_impl.cpp">
       <Filter>Code\impl\portable</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\impl\portable\portable_schema.cpp">
+      <Filter>Code\impl\portable</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h">
@@ -228,6 +231,9 @@
     <ClInclude Include="..\..\include\ignite\impl\interop\interop_stream_position_guard.h">
       <Filter>Code\impl\interop</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\portable\portable_schema.h">
+      <Filter>Code\impl\portable</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Code">

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
index 0514f92..02e894c 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_input_stream.cpp
@@ -188,7 +188,7 @@ namespace ignite
                 data = mem->Data();
                 len = mem->Length();
             }
-            
+
             void InteropInputStream::EnsureEnoughData(int32_t cnt) const
             {
                 if (len - pos < cnt) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/b85fa171/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
index 31727c7..1fd400b 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_output_stream.cpp
@@ -180,6 +180,17 @@ namespace ignite
                 pos = val;
             }
 
+            int32_t InteropOutputStream::Reserve(int32_t num)
+            {
+                EnsureCapacity(pos + num);
+
+                int32_t res = pos;
+
+                Shift(num);
+
+                return res;
+            }
+
             void InteropOutputStream::Synchronize()
             {
                 mem->Length(pos);