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/28 09:42:38 UTC

[03/17] ignite git commit: IGNITE-1619: Reworked serialization of generic collections.

IGNITE-1619: Reworked serialization of generic collections.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f65a53e4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f65a53e4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f65a53e4

Branch: refs/heads/ignite-950-new
Commit: f65a53e419346a45e2e26f4c4da84107d227e45f
Parents: b1b5428
Author: Pavel Tupitsyn <pt...@gridgain.com>
Authored: Fri Oct 23 11:22:22 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Oct 23 11:22:22 2015 +0300

----------------------------------------------------------------------
 .../cache/affinity/PlatformAffinity.java        |   5 +-
 .../Compute/ComputeApiTest.cs                   |  27 +-
 .../Apache.Ignite.Core.Tests/LifecycleTest.cs   |   3 +-
 .../Portable/PortableApiSelfTest.cs             | 112 +++----
 .../Portable/PortableSelfTest.cs                | 235 ++++++++++----
 .../Apache.Ignite.Core.csproj                   |   2 +-
 .../Apache.Ignite.Core/Cache/ICacheAffinity.cs  |   4 +-
 .../dotnet/Apache.Ignite.Core/Ignition.cs       |   4 +-
 .../Impl/Cache/CacheAffinityImpl.cs             |  10 +-
 .../Apache.Ignite.Core/Impl/Cache/CacheImpl.cs  |   2 +-
 .../Impl/Cache/Store/CacheStore.cs              |   5 +-
 .../Impl/Cluster/ClusterGroupImpl.cs            |   7 +-
 .../Impl/Cluster/ClusterNodeImpl.cs             |   7 +-
 .../Impl/Common/DelegateConverter.cs            |  30 +-
 .../Portable/Metadata/PortableMetadataImpl.cs   |   2 +-
 .../Impl/Portable/PortableBuilderImpl.cs        |  23 +-
 .../Impl/Portable/PortableCollectionInfo.cs     | 251 ---------------
 .../Impl/Portable/PortableReaderExtensions.cs   |  52 +++
 .../Impl/Portable/PortableReaderImpl.cs         |  70 +----
 .../Impl/Portable/PortableReflectiveRoutines.cs |  36 +--
 .../Impl/Portable/PortableSystemHandlers.cs     | 277 +++-------------
 .../Impl/Portable/PortableUtils.cs              | 314 +++++--------------
 .../Impl/Portable/PortableWriterImpl.cs         |  93 +-----
 .../Portable/IPortableRawReader.cs              |  31 +-
 .../Portable/IPortableRawWriter.cs              |  31 +-
 .../Portable/IPortableReader.cs                 |  47 +--
 .../Portable/IPortableWriter.cs                 |  33 +-
 27 files changed, 538 insertions(+), 1175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinity.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinity.java
index 9dd7416..0d2098b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinity.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/affinity/PlatformAffinity.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.portable.PortableRawReaderEx;
 import org.apache.ignite.internal.portable.PortableRawWriterEx;
 import org.apache.ignite.internal.processors.platform.PlatformAbstractTarget;
 import org.apache.ignite.internal.processors.platform.PlatformContext;
+import org.apache.ignite.internal.processors.platform.utils.PlatformUtils;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
@@ -248,7 +249,7 @@ public class PlatformAffinity extends PlatformAbstractTarget {
             }
 
             case OP_MAP_KEYS_TO_NODES: {
-                Collection<Object> keys = reader.readCollection();
+                Collection<Object> keys = PlatformUtils.readCollection(reader);
 
                 Map<ClusterNode, Collection<Object>> map = aff.mapKeysToNodes(keys);
 
@@ -265,7 +266,7 @@ public class PlatformAffinity extends PlatformAbstractTarget {
             }
 
             case OP_MAP_PARTITIONS_TO_NODES: {
-                Collection<Integer> parts = reader.readCollection();
+                Collection<Integer> parts = PlatformUtils.readCollection(reader);
 
                 Map<Integer, ClusterNode> map = aff.mapPartitionsToNodes(parts);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
index f7ab05b..4c451e7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -19,6 +19,7 @@
 namespace Apache.Ignite.Core.Tests.Compute
 {
     using System;
+    using System.Collections;
     using System.Collections.Generic;
     using System.Linq;
     using System.Threading;
@@ -786,12 +787,12 @@ namespace Apache.Ignite.Core.Tests.Compute
             Assert.AreEqual(1, res1.Length);
             Assert.AreEqual(1, res1[0]);
 
-            IList<int> res2 = _grid1.GetCompute().ExecuteJavaTask<IList<int>>(EchoTask, EchoTypeCollection);
+            var res2 = _grid1.GetCompute().ExecuteJavaTask<IList>(EchoTask, EchoTypeCollection);
 
             Assert.AreEqual(1, res2.Count);
             Assert.AreEqual(1, res2[0]);
 
-            IDictionary<int, int> res3 = _grid1.GetCompute().ExecuteJavaTask<IDictionary<int, int>>(EchoTask, EchoTypeMap);
+            var res3 = _grid1.GetCompute().ExecuteJavaTask<IDictionary>(EchoTask, EchoTypeMap);
 
             Assert.AreEqual(1, res3.Count);
             Assert.AreEqual(1, res3[1]);
@@ -846,12 +847,12 @@ namespace Apache.Ignite.Core.Tests.Compute
         [Test]
         public void TestEchoTaskPortableArray()
         {
-            var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputePortable[]>(EchoTask, EchoTypePortableArray);
+            var res = _grid1.GetCompute().ExecuteJavaTask<object[]>(EchoTask, EchoTypePortableArray);
             
             Assert.AreEqual(3, res.Length);
 
             for (var i = 0; i < res.Length; i++)
-                Assert.AreEqual(i + 1, res[i].Field);
+                Assert.AreEqual(i + 1, ((PlatformComputePortable) res[i]).Field);
         }
 
         /// <summary>
@@ -906,7 +907,7 @@ namespace Apache.Ignite.Core.Tests.Compute
         [Test]
         public void TestBroadcastTask()
         {
-            ICollection<Guid> res = _grid1.GetCompute().ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null);
+            var res = _grid1.GetCompute().ExecuteJavaTask<ICollection>(BroadcastTask, null).OfType<Guid>().ToList();
 
             Assert.AreEqual(3, res.Count);
             Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
@@ -917,7 +918,7 @@ namespace Apache.Ignite.Core.Tests.Compute
 
             Assert.AreEqual(2, prj.GetNodes().Count);
 
-            ICollection<Guid> filteredRes = prj.GetCompute().ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null);
+            var filteredRes = prj.GetCompute().ExecuteJavaTask<ICollection>(BroadcastTask, null).OfType<Guid>().ToList();
 
             Assert.AreEqual(2, filteredRes.Count);
             Assert.IsTrue(filteredRes.Contains(res.ElementAt(0)));
@@ -931,8 +932,8 @@ namespace Apache.Ignite.Core.Tests.Compute
         public void TestBroadcastTaskAsync()
         {
             var gridCompute = _grid1.GetCompute().WithAsync();
-            Assert.IsNull(gridCompute.ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null));
-            ICollection<Guid> res = gridCompute.GetFuture<ICollection<Guid>>().Get();
+            Assert.IsNull(gridCompute.ExecuteJavaTask<ICollection>(BroadcastTask, null));
+            var res = gridCompute.GetFuture<ICollection>().Get().OfType<Guid>().ToList();
 
             Assert.AreEqual(3, res.Count);
             Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
@@ -944,8 +945,8 @@ namespace Apache.Ignite.Core.Tests.Compute
             Assert.AreEqual(2, prj.GetNodes().Count);
 
             var compute = prj.GetCompute().WithAsync();
-            Assert.IsNull(compute.ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null));
-            ICollection<Guid> filteredRes = compute.GetFuture<ICollection<Guid>>().Get();
+            Assert.IsNull(compute.ExecuteJavaTask<IList>(BroadcastTask, null));
+            var filteredRes = compute.GetFuture<IList>().Get();
 
             Assert.AreEqual(2, filteredRes.Count);
             Assert.IsTrue(filteredRes.Contains(res.ElementAt(0)));
@@ -1051,7 +1052,8 @@ namespace Apache.Ignite.Core.Tests.Compute
         [Test]
         public void TestWithNoFailover()
         {
-            ICollection<Guid> res = _grid1.GetCompute().WithNoFailover().ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null);
+            var res = _grid1.GetCompute().WithNoFailover().ExecuteJavaTask<ICollection>(BroadcastTask, null)
+                .OfType<Guid>().ToList();
 
             Assert.AreEqual(3, res.Count);
             Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);
@@ -1065,7 +1067,8 @@ namespace Apache.Ignite.Core.Tests.Compute
         [Test]
         public void TestWithTimeout()
         {
-            ICollection<Guid> res = _grid1.GetCompute().WithTimeout(1000).ExecuteJavaTask<ICollection<Guid>>(BroadcastTask, null);
+            var res = _grid1.GetCompute().WithTimeout(1000).ExecuteJavaTask<ICollection>(BroadcastTask, null)
+                .OfType<Guid>().ToList();
 
             Assert.AreEqual(3, res.Count);
             Assert.AreEqual(1, _grid1.GetCluster().ForNodeIds(res.ElementAt(0)).GetNodes().Count);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
index 84f446c..dd79d43 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/LifecycleTest.cs
@@ -18,6 +18,7 @@
 namespace Apache.Ignite.Core.Tests
 {
     using System;
+    using System.Collections;
     using System.Collections.Generic;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl;
@@ -128,7 +129,7 @@ namespace Apache.Ignite.Core.Tests
             CheckEvent(AfterStartEvts[3], grid, grid, 0, null);
 
             // 2. Test Java start events.
-            IList<int> res = grid.GetCompute().ExecuteJavaTask<IList<int>>(
+            var res = grid.GetCompute().ExecuteJavaTask<IList>(
                 "org.apache.ignite.platform.lifecycle.PlatformJavaLifecycleTask", null);
 
             Assert.AreEqual(2, res.Count);

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableApiSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableApiSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableApiSelfTest.cs
index 009a2da..53e066d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableApiSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableApiSelfTest.cs
@@ -256,7 +256,8 @@ namespace Apache.Ignite.Core.Tests.Portable
             Assert.AreEqual(1, portObj.Deserialize<ToPortableNoMeta>().Val);
 
             // 5. Object array.
-            IPortableObject[] portObjArr = api.ToPortable<IPortableObject[]>(new[] { new ToPortable(1) });
+            var portObjArr = api.ToPortable<object[]>(new object[] {new ToPortable(1)})
+                .OfType<IPortableObject>().ToArray();
 
             Assert.AreEqual(1, portObjArr.Length);
             Assert.AreEqual(1, portObjArr[0].GetField<int>("Val"));
@@ -447,7 +448,7 @@ namespace Apache.Ignite.Core.Tests.Portable
             IPortableBuilder builderItem =
                 _grid.GetPortables().GetBuilder(typeof(BuilderCollectionItem)).SetField("val", 1);
 
-            builderCol.SetField<ICollection>("col", new List<IPortableBuilder> { builderItem });
+            builderCol.SetField<ICollection>("col", new ArrayList { builderItem });
 
             IPortableObject portCol = builderCol.Build();
 
@@ -458,11 +459,11 @@ namespace Apache.Ignite.Core.Tests.Portable
             Assert.AreEqual("col", meta.Fields.First());
             Assert.AreEqual(PortableTypeNames.TypeNameCollection, meta.GetFieldTypeName("col"));
 
-            ICollection<IPortableObject> portColItems = portCol.GetField<ICollection<IPortableObject>>("col");
+            var portColItems = portCol.GetField<ArrayList>("col");
 
             Assert.AreEqual(1, portColItems.Count);
 
-            IPortableObject portItem = portColItems.First();
+            var portItem = (IPortableObject) portColItems[0];
 
             meta = portItem.GetMetadata();
 
@@ -475,7 +476,7 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNotNull(col.Col);
             Assert.AreEqual(1, col.Col.Count);
-            Assert.AreEqual(1, col.Col.First().Val);
+            Assert.AreEqual(1, ((BuilderCollectionItem) col.Col[0]).Val);
 
             // Add more portable objects to collection.
             builderCol = _grid.GetPortables().GetBuilder(portCol);
@@ -498,10 +499,10 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.AreEqual(4, col.Col.Count);
 
-            BuilderCollectionItem item0 = col.Col.ElementAt(0);
-            BuilderCollectionItem item1 = col.Col.ElementAt(1);
-            BuilderCollectionItem item2 = col.Col.ElementAt(2);
-            BuilderCollectionItem item3 = col.Col.ElementAt(3);
+            var item0 = (BuilderCollectionItem) col.Col[0];
+            var item1 = (BuilderCollectionItem) col.Col[1];
+            var item2 = (BuilderCollectionItem) col.Col[2];
+            var item3 = (BuilderCollectionItem) col.Col[3];
 
             Assert.AreEqual(2, item0.Val);
 
@@ -525,8 +526,8 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             col = portCol.Deserialize<BuilderCollection>();
 
-            item0 = col.Col.ElementAt(0);
-            item1 = col.Col.ElementAt(1);
+            item0 = (BuilderCollectionItem) col.Col[0];
+            item1 = (BuilderCollectionItem) col.Col[1];
 
             Assert.AreEqual(3, item0.Val);
             Assert.AreSame(item0, item1);
@@ -918,7 +919,7 @@ namespace Apache.Ignite.Core.Tests.Portable
         public void TestCompositeArray()
         {
             // 1. Test simple array.
-            CompositeInner[] inArr = { new CompositeInner(1) };
+            object[] inArr = { new CompositeInner(1) };
 
             IPortableObject portObj = _grid.GetPortables().GetBuilder(typeof(CompositeArray)).SetHashCode(100)
                 .SetField("inArr", inArr).Build();
@@ -931,7 +932,7 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.AreEqual(100, portObj.GetHashCode());
 
-            IPortableObject[] portInArr = portObj.GetField<IPortableObject[]>("inArr");
+            IPortableObject[] portInArr = portObj.GetField<object[]>("inArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(1, portInArr.Length);
             Assert.AreEqual(1, portInArr[0].GetField<int>("val"));
@@ -940,17 +941,15 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.OutArr);
             Assert.AreEqual(1, arr.InArr.Length);
-            Assert.AreEqual(1, arr.InArr[0].Val);
+            Assert.AreEqual(1, ((CompositeInner) arr.InArr[0]).Val);
 
             // 2. Test addition to array.
-            portInArr = new[] { portInArr[0], null };
-
             portObj = _grid.GetPortables().GetBuilder(portObj).SetHashCode(200)
-                .SetField("inArr", portInArr).Build();
+                .SetField("inArr", new object[] { portInArr[0], null }).Build();
 
             Assert.AreEqual(200, portObj.GetHashCode());
 
-            portInArr = portObj.GetField<IPortableObject[]>("inArr");
+            portInArr = portObj.GetField<object[]>("inArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portInArr.Length);
             Assert.AreEqual(1, portInArr[0].GetField<int>("val"));
@@ -960,17 +959,17 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.OutArr);
             Assert.AreEqual(2, arr.InArr.Length);
-            Assert.AreEqual(1, arr.InArr[0].Val);
+            Assert.AreEqual(1, ((CompositeInner) arr.InArr[0]).Val);
             Assert.IsNull(arr.InArr[1]);
 
             portInArr[1] = _grid.GetPortables().GetBuilder(typeof(CompositeInner)).SetField("val", 2).Build();
 
             portObj = _grid.GetPortables().GetBuilder(portObj).SetHashCode(300)
-                .SetField("inArr", portInArr).Build();
+                .SetField("inArr", portInArr.OfType<object>().ToArray()).Build();
 
             Assert.AreEqual(300, portObj.GetHashCode());
 
-            portInArr = portObj.GetField<IPortableObject[]>("inArr");
+            portInArr = portObj.GetField<object[]>("inArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portInArr.Length);
             Assert.AreEqual(1, portInArr[0].GetField<int>("val"));
@@ -980,20 +979,20 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.OutArr);
             Assert.AreEqual(2, arr.InArr.Length);
-            Assert.AreEqual(1, arr.InArr[0].Val);
-            Assert.AreEqual(2, arr.InArr[1].Val);
+            Assert.AreEqual(1, ((CompositeInner)arr.InArr[0]).Val);
+            Assert.AreEqual(2, ((CompositeInner)arr.InArr[1]).Val);
 
             // 3. Test top-level handle inversion.
             CompositeInner inner = new CompositeInner(1);
 
-            inArr = new[] { inner, inner };
+            inArr = new object[] { inner, inner };
 
             portObj = _grid.GetPortables().GetBuilder(typeof(CompositeArray)).SetHashCode(100)
                 .SetField("inArr", inArr).Build();
 
             Assert.AreEqual(100, portObj.GetHashCode());
 
-            portInArr = portObj.GetField<IPortableObject[]>("inArr");
+            portInArr = portObj.GetField<object[]>("inArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portInArr.Length);
             Assert.AreEqual(1, portInArr[0].GetField<int>("val"));
@@ -1003,17 +1002,17 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.OutArr);
             Assert.AreEqual(2, arr.InArr.Length);
-            Assert.AreEqual(1, arr.InArr[0].Val);
-            Assert.AreEqual(1, arr.InArr[1].Val);
+            Assert.AreEqual(1, ((CompositeInner)arr.InArr[0]).Val);
+            Assert.AreEqual(1, ((CompositeInner)arr.InArr[1]).Val);
 
             portInArr[0] = _grid.GetPortables().GetBuilder(typeof(CompositeInner)).SetField("val", 2).Build();
 
             portObj = _grid.GetPortables().GetBuilder(portObj).SetHashCode(200)
-                .SetField("inArr", portInArr).Build();
+                .SetField("inArr", portInArr.ToArray<object>()).Build();
 
             Assert.AreEqual(200, portObj.GetHashCode());
 
-            portInArr = portObj.GetField<IPortableObject[]>("inArr");
+            portInArr = portObj.GetField<object[]>("inArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portInArr.Length);
             Assert.AreEqual(2, portInArr[0].GetField<int>("val"));
@@ -1023,14 +1022,14 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.OutArr);
             Assert.AreEqual(2, arr.InArr.Length);
-            Assert.AreEqual(2, arr.InArr[0].Val);
-            Assert.AreEqual(1, arr.InArr[1].Val);
+            Assert.AreEqual(2, ((CompositeInner)arr.InArr[0]).Val);
+            Assert.AreEqual(1, ((CompositeInner)arr.InArr[1]).Val);
 
             // 4. Test nested object handle inversion.
             CompositeOuter[] outArr = { new CompositeOuter(inner), new CompositeOuter(inner) };
 
             portObj = _grid.GetPortables().GetBuilder(typeof(CompositeArray)).SetHashCode(100)
-                .SetField("outArr", outArr).Build();
+                .SetField("outArr", outArr.ToArray<object>()).Build();
 
             meta = portObj.GetMetadata();
 
@@ -1041,7 +1040,7 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.AreEqual(100, portObj.GetHashCode());
 
-            IPortableObject[] portOutArr = portObj.GetField<IPortableObject[]>("outArr");
+            var portOutArr = portObj.GetField<object[]>("outArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portOutArr.Length);
             Assert.AreEqual(1, portOutArr[0].GetField<IPortableObject>("inner").GetField<int>("val"));
@@ -1051,18 +1050,18 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.InArr);
             Assert.AreEqual(2, arr.OutArr.Length);
-            Assert.AreEqual(1, arr.OutArr[0].Inner.Val);
-            Assert.AreEqual(1, arr.OutArr[1].Inner.Val);
+            Assert.AreEqual(1, ((CompositeOuter) arr.OutArr[0]).Inner.Val);
+            Assert.AreEqual(1, ((CompositeOuter) arr.OutArr[0]).Inner.Val);
 
             portOutArr[0] = _grid.GetPortables().GetBuilder(typeof(CompositeOuter))
                 .SetField("inner", new CompositeInner(2)).Build();
 
             portObj = _grid.GetPortables().GetBuilder(portObj).SetHashCode(200)
-                .SetField("outArr", portOutArr).Build();
+                .SetField("outArr", portOutArr.ToArray<object>()).Build();
 
             Assert.AreEqual(200, portObj.GetHashCode());
 
-            portInArr = portObj.GetField<IPortableObject[]>("outArr");
+            portInArr = portObj.GetField<object[]>("outArr").Cast<IPortableObject>().ToArray();
 
             Assert.AreEqual(2, portInArr.Length);
             Assert.AreEqual(2, portOutArr[0].GetField<IPortableObject>("inner").GetField<int>("val"));
@@ -1072,8 +1071,8 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             Assert.IsNull(arr.InArr);
             Assert.AreEqual(2, arr.OutArr.Length);
-            Assert.AreEqual(2, arr.OutArr[0].Inner.Val);
-            Assert.AreEqual(1, arr.OutArr[1].Inner.Val);
+            Assert.AreEqual(2, ((CompositeOuter)arr.OutArr[0]).Inner.Val);
+            Assert.AreEqual(1, ((CompositeOuter)arr.OutArr[1]).Inner.Val);
         }
 
         /// <summary>
@@ -1083,60 +1082,40 @@ namespace Apache.Ignite.Core.Tests.Portable
         public void TestCompositeContainer()
         {
             ArrayList col = new ArrayList();
-            ICollection<CompositeInner> gCol = new List<CompositeInner>();
             IDictionary dict = new Hashtable();
-            IDictionary<int, CompositeInner> gDict = new Dictionary<int, CompositeInner>();
 
             col.Add(new CompositeInner(1));
-            gCol.Add(new CompositeInner(2));
             dict[3] = new CompositeInner(3);
-            gDict[4] = new CompositeInner(4);
 
             IPortableObject portObj = _grid.GetPortables().GetBuilder(typeof(CompositeContainer)).SetHashCode(100)
                 .SetField<ICollection>("col", col)
-                .SetField("gCol", gCol)
-                .SetField("dict", dict)
-                .SetField("gDict", gDict).Build();
+                .SetField("dict", dict).Build();
 
             // 1. Check meta.
             IPortableMetadata meta = portObj.GetMetadata();
 
             Assert.AreEqual(typeof(CompositeContainer).Name, meta.TypeName);
 
-            Assert.AreEqual(4, meta.Fields.Count);
+            Assert.AreEqual(2, meta.Fields.Count);
             Assert.AreEqual(PortableTypeNames.TypeNameCollection, meta.GetFieldTypeName("col"));
-            Assert.AreEqual(PortableTypeNames.TypeNameCollection, meta.GetFieldTypeName("gCol"));
             Assert.AreEqual(PortableTypeNames.TypeNameMap, meta.GetFieldTypeName("dict"));
-            Assert.AreEqual(PortableTypeNames.TypeNameMap, meta.GetFieldTypeName("gDict"));
 
             // 2. Check in portable form.
             Assert.AreEqual(1, portObj.GetField<ICollection>("col").Count);
             Assert.AreEqual(1, portObj.GetField<ICollection>("col").OfType<IPortableObject>().First()
                 .GetField<int>("val"));
 
-            Assert.AreEqual(1, portObj.GetField<ICollection<IPortableObject>>("gCol").Count);
-            Assert.AreEqual(2, portObj.GetField<ICollection<IPortableObject>>("gCol").First().GetField<int>("val"));
-
             Assert.AreEqual(1, portObj.GetField<IDictionary>("dict").Count);
             Assert.AreEqual(3, ((IPortableObject) portObj.GetField<IDictionary>("dict")[3]).GetField<int>("val"));
 
-            Assert.AreEqual(1, portObj.GetField<IDictionary<int, IPortableObject>>("gDict").Count);
-            Assert.AreEqual(4, portObj.GetField<IDictionary<int, IPortableObject>>("gDict")[4].GetField<int>("val"));
-
             // 3. Check in deserialized form.
             CompositeContainer obj = portObj.Deserialize<CompositeContainer>();
 
             Assert.AreEqual(1, obj.Col.Count);
             Assert.AreEqual(1, obj.Col.OfType<CompositeInner>().First().Val);
 
-            Assert.AreEqual(1, obj.GCol.Count);
-            Assert.AreEqual(2, obj.GCol.First().Val);
-
             Assert.AreEqual(1, obj.Dict.Count);
             Assert.AreEqual(3, ((CompositeInner) obj.Dict[3]).Val);
-
-            Assert.AreEqual(1, obj.GDict.Count);
-            Assert.AreEqual(4, obj.GDict[4].Val);
         }
 
         /// <summary>
@@ -1587,8 +1566,8 @@ namespace Apache.Ignite.Core.Tests.Portable
     /// </summary>
     public class CompositeArray
     {
-        public CompositeInner[] InArr;
-        public CompositeOuter[] OutArr;
+        public object[] InArr;
+        public object[] OutArr;
     }
 
     /// <summary>
@@ -1597,10 +1576,7 @@ namespace Apache.Ignite.Core.Tests.Portable
     public class CompositeContainer
     {
         public ICollection Col;
-        public ICollection<CompositeInner> GCol;
-
         public IDictionary Dict;
-        public IDictionary<int, CompositeInner> GDict;
     }
 
     /// <summary>
@@ -1719,13 +1695,13 @@ namespace Apache.Ignite.Core.Tests.Portable
     public class BuilderCollection
     {
         /** */
-        public ICollection<BuilderCollectionItem> Col;
+        public readonly ArrayList Col;
 
         /// <summary>
         ///
         /// </summary>
         /// <param name="col"></param>
-        public BuilderCollection(ICollection<BuilderCollectionItem> col)
+        public BuilderCollection(ArrayList col)
         {
             Col = col;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
index 36faf36..f06bf43 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Portable/PortableSelfTest.cs
@@ -551,22 +551,55 @@ namespace Apache.Ignite.Core.Tests.Portable
         [Test]
         public void TestGenericCollections()
         {
-            ICollection<string> list = new List<string>();
+            var list = new List<string> {"1"};
 
-            list.Add("1");
+            var data = _marsh.Marshal(list);
 
-            byte[] data = _marsh.Marshal(list);
+            var newObjList = _marsh.Unmarshal<IList<string>>(data);
 
-            ICollection<object> newObjList = _marsh.Unmarshal<List<object>>(data);
+            CollectionAssert.AreEquivalent(list, newObjList);
+        }
 
-            Assert.NotNull(newObjList);
+        /// <summary>
+        /// Tests marshal aware type with generic collections.
+        /// </summary>
+        [Test]
+        public void TestGenericCollectionsType()
+        {
+            var marsh = new PortableMarshaller(new PortableConfiguration
+            {
+                TypeConfigurations = new List<PortableTypeConfiguration>
+                {
+                    new PortableTypeConfiguration(typeof (PrimitiveFieldType)),
+                    new PortableTypeConfiguration(typeof (GenericCollectionsType<PrimitiveFieldType, SerializableObject>))
+                }
+            });
 
-            ICollection<string> newList = new List<string>();
+            var obj = new GenericCollectionsType<PrimitiveFieldType, SerializableObject>
+            {
+                Keys = new[] {new PrimitiveFieldType(), new PrimitiveFieldType()},
+                Values =
+                    new List<SerializableObject>
+                    {
+                        new SerializableObject {Foo = 1},
+                        new SerializableObject {Foo = 5}
+                    },
+                Pairs = new Dictionary<PrimitiveFieldType, SerializableObject>
+                {
+                    {new PrimitiveFieldType(), new SerializableObject {Foo = 10}},
+                    {new PrimitiveFieldType {PByte = 10}, new SerializableObject {Foo = 20}}
+                },
+                Objects = new object[] {1, 2, "3", 4.4}
+            };
+            
+            var data = marsh.Marshal(obj);
 
-            foreach (object obj in newObjList)
-                newList.Add((string)obj);
+            var result = marsh.Unmarshal<GenericCollectionsType<PrimitiveFieldType, SerializableObject>>(data);
 
-            CollectionAssert.AreEquivalent(list, newList);
+            CollectionAssert.AreEquivalent(obj.Keys, result.Keys);
+            CollectionAssert.AreEquivalent(obj.Values, result.Values);
+            CollectionAssert.AreEquivalent(obj.Pairs, result.Pairs);
+            CollectionAssert.AreEquivalent(obj.Objects, result.Objects);
         }
 
         /**
@@ -840,40 +873,42 @@ namespace Apache.Ignite.Core.Tests.Portable
         [Test]
         public void TestCollectionsReflective()
         {
-            ICollection<PortableTypeConfiguration> typeCfgs =
-                new List<PortableTypeConfiguration>();
-
-            typeCfgs.Add(new PortableTypeConfiguration(typeof(CollectionsType)));
-            typeCfgs.Add(new PortableTypeConfiguration(typeof(InnerObjectType)));
-
-            PortableConfiguration cfg = new PortableConfiguration();
-
-            cfg.TypeConfigurations = typeCfgs;
-
-            PortableMarshaller marsh = new PortableMarshaller(cfg);
-
-            CollectionsType obj = new CollectionsType();
-
-            ArrayList list = new ArrayList();
-
-            list.Add(true);
-            list.Add((byte)1);
-            list.Add((short)2);
-            list.Add('a');
-            list.Add(3);
-            list.Add((long)4);
-            list.Add((float)5);
-            list.Add((double)6);
-
-            list.Add("string");
-            list.Add(Guid.NewGuid());
-
-            InnerObjectType innerObj = new InnerObjectType();
-
-            innerObj.PInt1 = 1;
-            innerObj.PInt2 = 2;
+            var marsh = new PortableMarshaller(new PortableConfiguration
+            {
+                TypeConfigurations = new List<PortableTypeConfiguration>
+                {
+                    new PortableTypeConfiguration(typeof (CollectionsType)),
+                    new PortableTypeConfiguration(typeof (InnerObjectType))
+                }
+            });
             
-            list.Add(innerObj);
+            var obj = new CollectionsType
+            {
+                Hashtable = new Hashtable {{1, 2}, {3, 4}},
+                LinkedList = new LinkedList<int>(new[] {1, 2, 3}),
+                SortedDict = new SortedDictionary<string, int> {{"1", 2}},
+                Dict = new Dictionary<int, string> {{1, "2"}},
+                Arr = new[] {new InnerObjectType()}
+            };
+
+            var list = new ArrayList
+            {
+                true,
+                (byte) 1,
+                (short) 2,
+                'a',
+                3,
+                (long) 4,
+                (float) 5,
+                (double) 6,
+                "string",
+                Guid.NewGuid(),
+                new InnerObjectType
+                {
+                    PInt1 = 1,
+                    PInt2 = 2
+                }
+            };
 
             obj.Col1 = list;
 
@@ -1138,17 +1173,20 @@ namespace Apache.Ignite.Core.Tests.Portable
             DateTime?[] nDateArr = { DateTime.Now.ToUniversalTime() };
 
             // Use special object.
-            SpecialArray obj1 = new SpecialArray();
-
-            obj1.GuidArr = guidArr;
-            obj1.NGuidArr = nGuidArr;
-            obj1.DateArr = dateArr;
-            obj1.NDateArr = nDateArr;
+            SpecialArray obj1 = new SpecialArray
+            {
+                GuidArr = guidArr,
+                NGuidArr = nGuidArr,
+                DateArr = dateArr,
+                NDateArr = nDateArr
+            };
 
             byte[] bytes = marsh.Marshal(obj1);
 
             IPortableObject portObj = marsh.Unmarshal<IPortableObject>(bytes, PortableMode.ForcePortable);
 
+            Assert.IsNotNull(portObj.Deserialize<SpecialArray>());
+
             Assert.AreEqual(guidArr, portObj.GetField<Guid[]>("guidArr"));
             Assert.AreEqual(nGuidArr, portObj.GetField<Guid?[]>("nGuidArr"));
             Assert.AreEqual(dateArr, portObj.GetField<DateTime[]>("dateArr"));
@@ -1270,6 +1308,7 @@ namespace Apache.Ignite.Core.Tests.Portable
             }
         }
 
+        [Serializable]
         public class InnerObjectType
         {
             public int PInt1 { get; set; }
@@ -1306,36 +1345,70 @@ namespace Apache.Ignite.Core.Tests.Portable
 
             public ArrayList Col2 { get; set; }
 
+            public Hashtable Hashtable { get; set; }
+
+            public Dictionary<int, string> Dict { get; set; }
+
+            public InnerObjectType[] Arr { get; set; }
+
+            public SortedDictionary<string, int> SortedDict { get; set; }
+
+            public LinkedList<int> LinkedList { get; set; }
+
             /** <inheritdoc /> */
             public override bool Equals(object obj)
             {
                 if (this == obj)
                     return true;
 
-                if (obj != null && obj is CollectionsType)
-                {
-                    CollectionsType that = (CollectionsType)obj;
+                var that = obj as CollectionsType;
 
-                    return CompareCollections(Col1, that.Col1) && CompareCollections(Col2, that.Col2);
-                }
-                return false;
+                return that != null 
+                    && CompareCollections(Col1, that.Col1) 
+                    && CompareCollections(Col2, that.Col2)
+                    && CompareCollections(Hashtable, that.Hashtable)
+                    && CompareCollections(Dict, that.Dict)
+                    && CompareCollections(Arr, that.Arr)
+                    && CompareCollections(SortedDict, that.SortedDict)
+                    && CompareCollections(LinkedList, that.LinkedList);
             }
 
             /** <inheritdoc /> */
             public override int GetHashCode()
             {
-                int res = Col1 != null ? Col1.GetHashCode() : 0;
+                int res = 0;
 
-                res = 31 * res + (Col2 != null ? Col2.GetHashCode() : 0);
+                foreach (var col in new object[] {Col1, Col2, Hashtable, Dict, Arr, SortedDict, LinkedList})
+                    res = 31*res + (col != null ? col.GetHashCode() : 0);
 
                 return res;
             }
+        }
 
-            /** <inheritdoc /> */
-            public override string ToString()
+        public class GenericCollectionsType<TKey, TValue> : IPortableMarshalAware
+        {
+            public ICollection<TKey> Keys { get; set; }
+
+            public ICollection<TValue> Values { get; set; }
+
+            public IDictionary<TKey, TValue> Pairs { get; set; }
+
+            public ICollection<object> Objects { get; set; }
+
+            public void WritePortable(IPortableWriter writer)
+            {
+                writer.WriteObject("Keys", Keys);
+                writer.WriteObject("Values", Values);
+                writer.WriteObject("Pairs", Pairs);
+                writer.WriteObject("Objects", Objects);
+            }
+
+            public void ReadPortable(IPortableReader reader)
             {
-                return "CollectoinsType[col1=" + CollectionAsString(Col1) + 
-                    ", col2=" + CollectionAsString(Col2) + ']'; 
+                Keys = (ICollection<TKey>) reader.ReadObject<object>("Keys");
+                Values = (ICollection<TValue>) reader.ReadObject<object>("Values");
+                Pairs = (IDictionary<TKey, TValue>) reader.ReadObject<object>("Pairs");
+                Objects = (ICollection<object>) reader.ReadObject<object>("Objects");
             }
         }
 
@@ -1450,18 +1523,18 @@ namespace Apache.Ignite.Core.Tests.Portable
         {
             public void WritePortable(IPortableWriter writer)
             {
-                writer.WriteObjectArray("a", GuidArr);
-                writer.WriteObjectArray("b", NGuidArr);
-                writer.WriteObjectArray("c", DateArr);
-                writer.WriteObjectArray("d", NDateArr);
+                writer.WriteObject("a", GuidArr);
+                writer.WriteObject("b", NGuidArr);
+                writer.WriteObject("c", DateArr);
+                writer.WriteObject("d", NDateArr);
             }
 
             public void ReadPortable(IPortableReader reader)
             {
-                GuidArr = reader.ReadObjectArray<Guid>("a");
-                NGuidArr = reader.ReadObjectArray<Guid?>("b");
-                DateArr = reader.ReadObjectArray<DateTime>("c");
-                NDateArr = reader.ReadObjectArray<DateTime?>("d");
+                GuidArr = reader.ReadObject<Guid[]>("a");
+                NGuidArr = reader.ReadObject<Guid?[]>("b");
+                DateArr = reader.ReadObject<DateTime[]>("c");
+                NDateArr = reader.ReadObject<DateTime?[]>("d");
             }
         }
 
@@ -1472,6 +1545,7 @@ namespace Apache.Ignite.Core.Tests.Portable
             public TestEnum[] PEnumArray { get; set; }
         }
 
+        [Serializable]
         public class PrimitiveFieldType 
         {
             public bool PBool { get; set; }
@@ -2068,5 +2142,30 @@ namespace Apache.Ignite.Core.Tests.Portable
                 UtcArrRaw = rawReader.ReadDateArray(false);
             }
         }
+
+        [Serializable]
+        private class SerializableObject
+        {
+            public int Foo { get; set; }
+
+            private bool Equals(SerializableObject other)
+            {
+                return Foo == other.Foo;
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (ReferenceEquals(null, obj)) return false;
+                if (ReferenceEquals(this, obj)) return true;
+                if (obj.GetType() != GetType()) return false;
+
+                return Equals((SerializableObject) obj);
+            }
+
+            public override int GetHashCode()
+            {
+                return Foo;
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index a45d6ed..be96fd9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -257,7 +257,6 @@
     <Compile Include="Impl\Portable\Metadata\PortableMetadataImpl.cs" />
     <Compile Include="Impl\Portable\PortableBuilderField.cs" />
     <Compile Include="Impl\Portable\PortableBuilderImpl.cs" />
-    <Compile Include="Impl\Portable\PortableCollectionInfo.cs" />
     <Compile Include="Impl\Portable\PortableFullTypeDescriptor.cs" />
     <Compile Include="Impl\Portable\PortableHandleDictionary.cs" />
     <Compile Include="Impl\Portable\PortableMarshalAwareSerializer.cs" />
@@ -265,6 +264,7 @@
     <Compile Include="Impl\Portable\PortableMode.cs" />
     <Compile Include="Impl\Portable\PortableObjectHandle.cs" />
     <Compile Include="Impl\Portable\PortableOrSerializableObjectHolder.cs" />
+    <Compile Include="Impl\Portable\PortableReaderExtensions.cs" />
     <Compile Include="Impl\Portable\PortableReaderHandleDictionary.cs" />
     <Compile Include="Impl\Portable\PortableReaderImpl.cs" />
     <Compile Include="Impl\Portable\PortableReflectiveRoutines.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
index 64f34d7..f61fd4b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
@@ -114,7 +114,7 @@ namespace Apache.Ignite.Core.Cache
         /// </summary>
         /// <param name="keys">Keys to map to nodes.</param>
         /// <returns>Map of nodes to keys or empty map if there are no alive nodes for this cache.</returns>
-        IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IList<TK> keys);
+        IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IEnumerable<TK> keys);
 
         /// <summary>
         /// This method provides ability to detect to which primary node the given key
@@ -145,7 +145,7 @@ namespace Apache.Ignite.Core.Cache
         /// </summary>
         /// <param name="parts">Partition ids.</param>
         /// <returns>Mapping of given partitions to their primary nodes.</returns>
-        IDictionary<int, IClusterNode> MapPartitionsToNodes(IList<int> parts);
+        IDictionary<int, IClusterNode> MapPartitionsToNodes(IEnumerable<int> parts);
 
         /// <summary>
         /// Gets primary and backup nodes for partition. Note that primary node is always

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
index d02b5ac..6547c2b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs
@@ -335,7 +335,7 @@ namespace Apache.Ignite.Core
         /// </summary>
         /// <param name="reader">Reader.</param>
         /// <returns>Lifecycle bean.</returns>
-        internal static ILifecycleBean CreateLifecycleBean(PortableReaderImpl reader)
+        private static ILifecycleBean CreateLifecycleBean(PortableReaderImpl reader)
         {
             // 1. Instantiate.
             string assemblyName = reader.ReadString();
@@ -344,7 +344,7 @@ namespace Apache.Ignite.Core
             object bean = IgniteUtils.CreateInstance(assemblyName, clsName);
 
             // 2. Set properties.
-            IDictionary<string, object> props = reader.ReadGenericDictionary<string, object>();
+            var props = reader.ReadDictionaryAsGeneric<string, object>();
 
             IgniteUtils.SetProperties(bean, props);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheAffinityImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheAffinityImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheAffinityImpl.cs
index 37bf73a..4d9cd2d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheAffinityImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheAffinityImpl.cs
@@ -175,12 +175,12 @@ namespace Apache.Ignite.Core.Impl.Cache
         }
 
         /** <inheritDoc /> */
-        public IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IList<TK> keys)
+        public IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IEnumerable<TK> keys)
         {
             IgniteArgumentCheck.NotNull(keys, "keys");
 
-            return DoOutInOp(OpMapKeysToNodes, w => w.WriteObject(keys),
-                reader => ReadDictionary(reader, ReadNode, r => r.ReadObject<IList<TK>>()));
+            return DoOutInOp(OpMapKeysToNodes, w => WriteEnumerable(w, keys),
+                reader => ReadDictionary(reader, ReadNode, r => (IList<TK>) r.ReadCollectionAsList<TK>()));
         }
 
         /** <inheritDoc /> */
@@ -206,12 +206,12 @@ namespace Apache.Ignite.Core.Impl.Cache
         }
 
         /** <inheritDoc /> */
-        public IDictionary<int, IClusterNode> MapPartitionsToNodes(IList<int> parts)
+        public IDictionary<int, IClusterNode> MapPartitionsToNodes(IEnumerable<int> parts)
         {
             IgniteArgumentCheck.NotNull(parts, "parts");
 
             return DoOutInOp(OpMapPartitionsToNodes,
-                w => w.WriteObject(parts),
+                w => WriteEnumerable(w, parts),
                 reader => ReadDictionary(reader, r => r.ReadInt(), ReadNode));
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
index 5a01006..c689bb4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheImpl.cs
@@ -266,7 +266,7 @@ namespace Apache.Ignite.Core.Impl.Cache
                 else
                     writer.WriteObject<CacheEntryFilterHolder>(null);
 
-                writer.WriteObjectArray(args);
+                writer.WriteArray(args);
             });
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
index aac32c7..1eeb3a0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
@@ -17,7 +17,6 @@
 
 namespace Apache.Ignite.Core.Impl.Cache.Store
 {
-    using System;
     using System.Collections;
     using System.Diagnostics;
     using Apache.Ignite.Core.Cache.Store;
@@ -107,7 +106,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Store
                 var assemblyName = reader.ReadString();
                 var className = reader.ReadString();
                 var convertPortable = reader.ReadBoolean();
-                var propertyMap = reader.ReadGenericDictionary<string, object>();
+                var propertyMap = reader.ReadDictionaryAsGeneric<string, object>();
 
                 var store = (ICacheStore) IgniteUtils.CreateInstance(assemblyName, className);
 
@@ -166,7 +165,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Store
                 switch (opType)
                 {
                     case OpLoadCache:
-                        _store.LoadCache((k, v) => WriteObjects(cb, grid, k, v), rawReader.ReadObjectArray<object>());
+                        _store.LoadCache((k, v) => WriteObjects(cb, grid, k, v), rawReader.ReadArray<object>());
 
                         break;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
index b1f19ab..85762e3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
@@ -541,13 +541,10 @@ namespace Apache.Ignite.Core.Impl.Cluster
         public IPortableMetadata GetMetadata(int typeId)
         {
             return DoOutInOp<IPortableMetadata>(OpMetadata, 
-                writer =>
-                {
-                    writer.WriteInt(typeId);
-                },
+                writer => writer.WriteInt(typeId),
                 stream =>
                 {
-                    PortableReaderImpl reader = Marshaller.StartUnmarshal(stream, false);
+                    var reader = Marshaller.StartUnmarshal(stream, false);
 
                     return reader.ReadBoolean() ? new PortableMetadataImpl(reader) : null;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterNodeImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterNodeImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterNodeImpl.cs
index 1913cef..4e458f1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterNodeImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterNodeImpl.cs
@@ -23,6 +23,7 @@ namespace Apache.Ignite.Core.Impl.Cluster
     using Apache.Ignite.Core.Cluster;
     using Apache.Ignite.Core.Impl.Collections;
     using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Impl.Portable;
     using Apache.Ignite.Core.Portable;
 
     /// <summary>
@@ -72,9 +73,9 @@ namespace Apache.Ignite.Core.Impl.Cluster
 
             _id = id.Value;
 
-            _attrs = reader.ReadGenericDictionary<string, object>().AsReadOnly();
-            _addrs = reader.ReadGenericCollection<string>().AsReadOnly();
-            _hosts = reader.ReadGenericCollection<string>().AsReadOnly();
+            _attrs = reader.ReadDictionaryAsGeneric<string, object>().AsReadOnly();
+            _addrs = reader.ReadCollectionAsList<string>().AsReadOnly();
+            _hosts = reader.ReadCollectionAsList<string>().AsReadOnly();
             _order = reader.ReadLong();
             _isLocal = reader.ReadBoolean();
             _isDaemon = reader.ReadBoolean();

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
index 7f83588..d32d475 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/DelegateConverter.cs
@@ -148,18 +148,15 @@ namespace Apache.Ignite.Core.Impl.Common
         /// Compiles a generic ctor with arbitrary number of arguments.
         /// </summary>
         /// <typeparam name="T">Result func type.</typeparam>
-        /// <param name="type">Type to be created by ctor.</param>
+        /// <param name="ctor">Contructor info.</param>
         /// <param name="argTypes">Argument types.</param>
         /// <param name="convertResultToObject">if set to <c>true</c> [convert result to object].
-        /// Flag that indicates whether ctor return value should be converted to object.
-        /// </param>
+        /// Flag that indicates whether ctor return value should be converted to object.</param>
         /// <returns>
         /// Compiled generic constructor.
         /// </returns>
-        public static T CompileCtor<T>(Type type, Type[] argTypes, bool convertResultToObject = true)
+        public static T CompileCtor<T>(ConstructorInfo ctor, Type[] argTypes, bool convertResultToObject = true)
         {
-            var ctor = type.GetConstructor(argTypes);
-
             Debug.Assert(ctor != null);
 
             var args = new ParameterExpression[argTypes.Length];
@@ -175,12 +172,31 @@ namespace Apache.Ignite.Core.Impl.Common
             Expression ctorExpr = Expression.New(ctor, argsConverted);  // ctor takes args of specific types
 
             if (convertResultToObject)
-                ctorExpr = Expression.Convert(ctorExpr, typeof (object)); // convert ctor result to object
+                ctorExpr = Expression.Convert(ctorExpr, typeof(object)); // convert ctor result to object
 
             return Expression.Lambda<T>(ctorExpr, args).Compile();  // lambda takes args as objects
         }
 
         /// <summary>
+        /// Compiles a generic ctor with arbitrary number of arguments.
+        /// </summary>
+        /// <typeparam name="T">Result func type.</typeparam>
+        /// <param name="type">Type to be created by ctor.</param>
+        /// <param name="argTypes">Argument types.</param>
+        /// <param name="convertResultToObject">if set to <c>true</c> [convert result to object].
+        /// Flag that indicates whether ctor return value should be converted to object.
+        /// </param>
+        /// <returns>
+        /// Compiled generic constructor.
+        /// </returns>
+        public static T CompileCtor<T>(Type type, Type[] argTypes, bool convertResultToObject = true)
+        {
+            var ctor = type.GetConstructor(argTypes);
+
+            return CompileCtor<T>(ctor, argTypes, convertResultToObject);
+        }
+
+        /// <summary>
         /// Compiles the field setter.
         /// </summary>
         /// <param name="field">The field.</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/PortableMetadataImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/PortableMetadataImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/PortableMetadataImpl.cs
index 06578c0..4031d17 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/PortableMetadataImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/Metadata/PortableMetadataImpl.cs
@@ -124,7 +124,7 @@ namespace Apache.Ignite.Core.Impl.Portable.Metadata
             TypeId = reader.ReadInt();
             TypeName = reader.ReadString();
             AffinityKeyFieldName = reader.ReadString();
-            _fields = reader.ReadGenericDictionary<string, int>();
+            _fields = reader.ReadDictionaryAsGeneric<string, int>();
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
index 69c2811..3241c1c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
@@ -18,6 +18,7 @@
 namespace Apache.Ignite.Core.Impl.Portable
 {
     using System;
+    using System.Collections;
     using System.Collections.Generic;
     using System.Diagnostics.CodeAnalysis;
     using System.IO;
@@ -176,7 +177,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
             PortableWriterImpl writer = _portables.Marshaller.StartMarshal(outStream);
 
-            writer.Builder(this);
+            writer.SetBuilder(this);
 
             // All related builders will work in this context with this writer.
             _parent._ctx = new Context(writer);
@@ -282,7 +283,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             IDictionary<string, PortableBuilderField> vals)
         {
             // Set correct builder to writer frame.
-            PortableBuilderImpl oldBuilder = _parent._ctx.Writer.Builder(_parent);
+            PortableBuilderImpl oldBuilder = _parent._ctx.Writer.SetBuilder(_parent);
 
             int streamPos = inStream.Position;
             
@@ -312,7 +313,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                         // Write metadata if: 1) it is enabled for type; 2) type is not null (i.e. it is neither 
                         // remove marker, nor a field read through "GetField" method.
                         if (metaHnd != null && valEntry.Value.Type != null)
-                            metaHnd.OnFieldWrite(fieldId, valEntry.Key, TypeId(valEntry.Value.Type));
+                            metaHnd.OnFieldWrite(fieldId, valEntry.Key, GetTypeId(valEntry.Value.Type));
                     }
                 }
 
@@ -331,7 +332,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             finally
             {
                 // Restore builder frame.
-                _parent._ctx.Writer.Builder(oldBuilder);
+                _parent._ctx.Writer.SetBuilder(oldBuilder);
 
                 inStream.Seek(streamPos, SeekOrigin.Begin);
             }
@@ -747,20 +748,26 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// </summary>
         /// <param name="type">Type.</param>
         /// <returns>Type ID.</returns>
-        private static int TypeId(Type type)
+        private static int GetTypeId(Type type)
         {
             int typeId;
 
             if (TypeIds.TryGetValue(type, out typeId))
                 return typeId;
+
             if (type.IsEnum)
                 return PortableUtils.TypeEnum;
+
             if (type.IsArray)
                 return type.GetElementType().IsEnum ? PortableUtils.TypeArrayEnum : PortableUtils.TypeArray;
-            PortableCollectionInfo colInfo = PortableCollectionInfo.Info(type);
 
-            return colInfo.IsAny ? colInfo.IsCollection || colInfo.IsGenericCollection ?
-                PortableUtils.TypeCollection : PortableUtils.TypeDictionary : PortableUtils.TypeObject;
+            if (typeof (IDictionary).IsAssignableFrom(type))
+                return PortableUtils.TypeDictionary;
+            
+            if (typeof (ICollection).IsAssignableFrom(type))
+                return PortableUtils.TypeCollection;
+
+            return PortableUtils.TypeObject;
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs
deleted file mode 100644
index fc61833..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableCollectionInfo.cs
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Impl.Portable
-{
-    using System;
-    using System.Collections.Concurrent;
-    using System.Collections.Generic;
-    using System.Diagnostics;
-    using System.Reflection;
-    using Apache.Ignite.Core.Impl.Common;
-
-    /**
-     * <summary>Collection info helper.</summary>
-     */
-    internal class PortableCollectionInfo
-    {
-        /** Flag: none. */
-        private const byte FlagNone = 0;
-
-        /** Flag: generic dictionary. */
-        private const byte FlagGenericDictionary = 1;
-
-        /** Flag: generic collection. */
-        private const byte FlagGenericCollection = 2;
-
-        /** Flag: dictionary. */
-        private const byte FlagDictionary = 3;
-
-        /** Flag: collection. */
-        private const byte FlagCollection = 4;
-
-        /** Cache "none" value. */
-        private static readonly PortableCollectionInfo None =
-            new PortableCollectionInfo(FlagNone, null, null, null);
-
-        /** Cache "dictionary" value. */
-        private static readonly PortableCollectionInfo Dictionary =
-            new PortableCollectionInfo(FlagDictionary, PortableSystemHandlers.WriteHndDictionary, null, null);
-
-        /** Cache "collection" value. */
-        private static readonly PortableCollectionInfo Collection =
-            new PortableCollectionInfo(FlagCollection, PortableSystemHandlers.WriteHndCollection, null, null);
-
-        /** Cached infos. */
-        private static readonly IDictionary<Type, PortableCollectionInfo> Infos =
-            new ConcurrentDictionary<Type, PortableCollectionInfo>(64, 32);
-
-        /**
-         * <summary>Get collection info for type.</summary>
-         * <param name="type">Type.</param>
-         * <returns>Collection info.</returns>
-         */
-        public static PortableCollectionInfo Info(Type type)
-        {
-            PortableCollectionInfo info;
-
-            if (!Infos.TryGetValue(type, out info))
-            {
-                info = Info0(type);
-
-                Infos[type] = info;
-            }
-
-            return info;
-        }
-
-        /**
-         * <summary>Internal routine to get collection info for type.</summary>
-         * <param name="type">Type.</param>
-         * <returns>Collection info.</returns>
-         */
-        private static PortableCollectionInfo Info0(Type type)
-        {
-            if (type.IsGenericType)
-            {
-                if (type.GetGenericTypeDefinition() == PortableUtils.TypGenericDictionary)
-                {
-                    MethodInfo writeMthd =
-                        PortableUtils.MtdhWriteGenericDictionary.MakeGenericMethod(type.GetGenericArguments());
-                    MethodInfo readMthd =
-                        PortableUtils.MtdhReadGenericDictionary.MakeGenericMethod(type.GetGenericArguments());
-
-                    return new PortableCollectionInfo(FlagGenericDictionary,
-                        PortableSystemHandlers.WriteHndGenericDictionary, writeMthd, readMthd);
-                }
-
-                Type genTyp = type.GetInterface(PortableUtils.TypGenericDictionary.FullName);
-
-                if (genTyp != null)
-                {
-                    MethodInfo writeMthd =
-                        PortableUtils.MtdhWriteGenericDictionary.MakeGenericMethod(genTyp.GetGenericArguments());
-                    MethodInfo readMthd =
-                        PortableUtils.MtdhReadGenericDictionary.MakeGenericMethod(genTyp.GetGenericArguments());
-
-                    return new PortableCollectionInfo(FlagGenericDictionary,
-                        PortableSystemHandlers.WriteHndGenericDictionary, writeMthd, readMthd);
-                }
-
-                if (type.GetGenericTypeDefinition() == PortableUtils.TypGenericCollection)
-                {
-                    MethodInfo writeMthd =
-                        PortableUtils.MtdhWriteGenericCollection.MakeGenericMethod(type.GetGenericArguments());
-                    MethodInfo readMthd =
-                        PortableUtils.MtdhReadGenericCollection.MakeGenericMethod(type.GetGenericArguments());
-
-                    return new PortableCollectionInfo(FlagGenericCollection,
-                        PortableSystemHandlers.WriteHndGenericCollection, writeMthd, readMthd);
-                }
-
-                genTyp = type.GetInterface(PortableUtils.TypGenericCollection.FullName);
-
-                if (genTyp != null)
-                {
-                    MethodInfo writeMthd =
-                        PortableUtils.MtdhWriteGenericCollection.MakeGenericMethod(genTyp.GetGenericArguments());
-                    MethodInfo readMthd =
-                        PortableUtils.MtdhReadGenericCollection.MakeGenericMethod(genTyp.GetGenericArguments());
-
-                    return new PortableCollectionInfo(FlagGenericCollection,
-                        PortableSystemHandlers.WriteHndGenericCollection, writeMthd, readMthd);
-                }
-            }
-
-            if (type == PortableUtils.TypDictionary || type.GetInterface(PortableUtils.TypDictionary.FullName) != null)
-                return Dictionary;
-            if (type == PortableUtils.TypCollection || type.GetInterface(PortableUtils.TypCollection.FullName) != null)
-                return Collection;
-            return None;
-        }
-
-        /** Flag. */
-        private readonly byte _flag;
-
-        /** Write handler. */
-        private readonly PortableSystemWriteDelegate _writeHnd;
-
-        /** Generic write func. */
-        private readonly Action<object, PortableWriterImpl> _writeFunc;
-
-        /** Generic read func. */
-        private readonly Func<PortableReaderImpl, object, object> _readFunc;
-
-        /**
-         * <summary>Constructor.</summary>
-         * <param name="flag0">Flag.</param>
-         * <param name="writeHnd0">Write handler.</param>
-         * <param name="writeMthd0">Generic write method.</param>
-         * <param name="readMthd0">Generic read method.</param>
-         */
-        private PortableCollectionInfo(byte flag0, PortableSystemWriteDelegate writeHnd0,
-            MethodInfo writeMthd0, MethodInfo readMthd0)
-        {
-            _flag = flag0;
-            _writeHnd = writeHnd0;
-
-            if (writeMthd0 != null)
-                _writeFunc = DelegateConverter.CompileFunc<Action<object, PortableWriterImpl>>(null, writeMthd0, null,
-                    new[] {true, false, false});
-
-            if (readMthd0 != null)
-                _readFunc = DelegateConverter.CompileFunc<Func<PortableReaderImpl, object, object>>(null, readMthd0, 
-                    null, new[] {false, true, false});
-        }
-
-        /**
-         * <summary>Generic dictionary flag.</summary>
-         */
-        public bool IsGenericDictionary
-        {
-            get { return _flag == FlagGenericDictionary; }
-        }
-
-        /**
-         * <summary>Generic collection flag.</summary>
-         */
-        public bool IsGenericCollection
-        {
-            get { return _flag == FlagGenericCollection; }
-        }
-
-        /**
-         * <summary>Dictionary flag.</summary>
-         */
-        public bool IsDictionary
-        {
-            get { return _flag == FlagDictionary; }
-        }
-
-        /**
-         * <summary>Collection flag.</summary>
-         */
-        public bool IsCollection
-        {
-            get { return _flag == FlagCollection; }
-        }
-
-        /**
-         * <summary>Whether at least one flag is set..</summary>
-         */
-        public bool IsAny
-        {
-            get { return _flag != FlagNone; }
-        }
-
-        /**
-         * <summary>Write handler.</summary>
-         */
-        public PortableSystemWriteDelegate WriteHandler
-        {
-            get { return _writeHnd; }
-        }
-
-        /// <summary>
-        /// Reads the generic collection.
-        /// </summary>
-        public object ReadGeneric(PortableReaderImpl reader)
-        {
-            Debug.Assert(reader != null);
-            Debug.Assert(_readFunc != null);
-
-            return _readFunc(reader, null);
-        }
-
-        /// <summary>
-        /// Writes the generic collection.
-        /// </summary>
-        public void WriteGeneric(PortableWriterImpl writer, object value)
-        {
-            Debug.Assert(writer != null);
-            Debug.Assert(_writeFunc != null);
-
-            _writeFunc(value, writer);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs
new file mode 100644
index 0000000..3f0de91
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderExtensions.cs
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.Portable
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Reader extensions.
+    /// </summary>
+    internal static class PortableReaderExtensions
+    {
+        /// <summary>
+        /// Reads untyped collection as a generic list.
+        /// </summary>
+        /// <typeparam name="T">Type of list element.</typeparam>
+        /// <param name="reader">The reader.</param>
+        /// <returns>Resulting generic list.</returns>
+        public static List<T> ReadCollectionAsList<T>(this IPortableRawReader reader)
+        {
+            return ((List<T>) reader.ReadCollection(size => new List<T>(size),
+                (col, elem) => ((List<T>) col).Add((T) elem)));
+        }
+
+        /// <summary>
+        /// Reads untyped dictionary as generic dictionary.
+        /// </summary>
+        /// <typeparam name="TKey">The type of the key.</typeparam>
+        /// <typeparam name="TValue">The type of the value.</typeparam>
+        /// <param name="reader">The reader.</param>
+        /// <returns>Resulting dictionary.</returns>
+        public static Dictionary<TKey, TValue> ReadDictionaryAsGeneric<TKey, TValue>(this IPortableRawReader reader)
+        {
+            return (Dictionary<TKey, TValue>) reader.ReadDictionary(size => new Dictionary<TKey, TValue>(size));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
index dd78702..6e06007 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
@@ -385,13 +385,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /** <inheritdoc /> */
         public string[] ReadStringArray(string fieldName)
         {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericArray<string>(r, false));
+            return ReadField(fieldName, r => PortableUtils.ReadArray<string>(r, false));
         }
 
         /** <inheritdoc /> */
         public string[] ReadStringArray()
         {
-            return Read(r => PortableUtils.ReadGenericArray<string>(r, false));
+            return Read(r => PortableUtils.ReadArray<string>(r, false));
         }
 
         /** <inheritdoc /> */
@@ -409,13 +409,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /** <inheritdoc /> */
         public Guid?[] ReadGuidArray(string fieldName)
         {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericArray<Guid?>(r, false));
+            return ReadField(fieldName, r => PortableUtils.ReadArray<Guid?>(r, false));
         }
 
         /** <inheritdoc /> */
         public Guid?[] ReadGuidArray()
         {
-            return Read(r => PortableUtils.ReadGenericArray<Guid?>(r, false));
+            return Read(r => PortableUtils.ReadArray<Guid?>(r, false));
         }
 
         /** <inheritdoc /> */
@@ -433,13 +433,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /** <inheritdoc /> */
         public T[] ReadEnumArray<T>(string fieldName)
         {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericArray<T>(r, true));
+            return ReadField(fieldName, r => PortableUtils.ReadArray<T>(r, true));
         }
 
         /** <inheritdoc /> */
         public T[] ReadEnumArray<T>()
         {
-            return Read(r => PortableUtils.ReadGenericArray<T>(r, true));
+            return Read(r => PortableUtils.ReadArray<T>(r, true));
         }
 
         /** <inheritdoc /> */
@@ -463,15 +463,15 @@ namespace Apache.Ignite.Core.Impl.Portable
         }
 
         /** <inheritdoc /> */
-        public T[] ReadObjectArray<T>(string fieldName)
+        public T[] ReadArray<T>(string fieldName)
         {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericArray<T>(r, true));
+            return ReadField(fieldName, r => PortableUtils.ReadArray<T>(r, true));
         }
 
         /** <inheritdoc /> */
-        public T[] ReadObjectArray<T>()
+        public T[] ReadArray<T>()
         {
-            return Read(r => PortableUtils.ReadGenericArray<T>(r, true));
+            return Read(r => PortableUtils.ReadArray<T>(r, true));
         }
 
         /** <inheritdoc /> */
@@ -501,31 +501,6 @@ namespace Apache.Ignite.Core.Impl.Portable
         }
 
         /** <inheritdoc /> */
-        public ICollection<T> ReadGenericCollection<T>(string fieldName)
-        {
-            return ReadGenericCollection<T>(fieldName, null);
-        }
-
-        /** <inheritdoc /> */
-        public ICollection<T> ReadGenericCollection<T>()
-        {
-            return ReadGenericCollection((PortableGenericCollectionFactory<T>) null);
-        }
-
-        /** <inheritdoc /> */
-        public ICollection<T> ReadGenericCollection<T>(string fieldName,
-            PortableGenericCollectionFactory<T> factory)
-        {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericCollection(r, factory));
-        }
-
-        /** <inheritdoc /> */
-        public ICollection<T> ReadGenericCollection<T>(PortableGenericCollectionFactory<T> factory)
-        {
-            return Read(r => PortableUtils.ReadGenericCollection(r, factory));
-        }
-
-        /** <inheritdoc /> */
         public IDictionary ReadDictionary(string fieldName)
         {
             return ReadDictionary(fieldName, null);
@@ -549,31 +524,6 @@ namespace Apache.Ignite.Core.Impl.Portable
             return Read(r => PortableUtils.ReadDictionary(r, factory));
         }
 
-        /** <inheritdoc /> */
-        public IDictionary<TK, TV> ReadGenericDictionary<TK, TV>(string fieldName)
-        {
-            return ReadGenericDictionary<TK, TV>(fieldName, null);
-        }
-
-        /** <inheritdoc /> */
-        public IDictionary<TK, TV> ReadGenericDictionary<TK, TV>()
-        {
-            return ReadGenericDictionary((PortableGenericDictionaryFactory<TK, TV>) null);
-        }
-
-        /** <inheritdoc /> */
-        public IDictionary<TK, TV> ReadGenericDictionary<TK, TV>(string fieldName,
-            PortableGenericDictionaryFactory<TK, TV> factory)
-        {
-            return ReadField(fieldName, r => PortableUtils.ReadGenericDictionary(r, factory));
-        }
-
-        /** <inheritdoc /> */
-        public IDictionary<TK, TV> ReadGenericDictionary<TK, TV>(PortableGenericDictionaryFactory<TK, TV> factory)
-        {
-            return Read(r => PortableUtils.ReadGenericDictionary(r, factory));
-        }
-
         /// <summary>
         /// Enable detach mode for the next object read. 
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f65a53e4/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs
index 907c480..261a172 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReflectiveRoutines.cs
@@ -55,15 +55,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
         /** Method: read array. */
         private static readonly MethodInfo MthdReadObjArray =
-            typeof(IPortableReader).GetMethod("ReadObjectArray", new[] { typeof(string) });
-
-        /** Method: read generic collection. */
-        private static readonly MethodInfo MthdReadGenericCollection =
-            typeof(IPortableReader).GetMethod("ReadGenericCollection", new[] { typeof(string) });
-
-        /** Method: read generic dictionary. */
-        private static readonly MethodInfo MthdReadGenericDictionary =
-            typeof(IPortableReader).GetMethod("ReadGenericDictionary", new[] { typeof(string) });
+            typeof(IPortableReader).GetMethod("ReadArray", new[] { typeof(string) });
 
         /** Method: read object. */
         private static readonly MethodInfo MthdReadObj=
@@ -75,15 +67,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
         /** Method: write array. */
         private static readonly MethodInfo MthdWriteObjArray =
-            typeof(IPortableWriter).GetMethod("WriteObjectArray");
-
-        /** Method: write generic collection. */
-        private static readonly MethodInfo MthdWriteGenericCollection =
-            typeof(IPortableWriter).GetMethod("WriteGenericCollection");
-
-        /** Method: write generic dictionary. */
-        private static readonly MethodInfo MthdWriteGenericDictionary =
-            typeof(IPortableWriter).GetMethod("WriteGenericDictionary");
+            typeof(IPortableWriter).GetMethod("WriteArray");
 
         /** Method: read object. */
         private static readonly MethodInfo MthdWriteObj =
@@ -339,24 +323,12 @@ namespace Apache.Ignite.Core.Impl.Portable
                 writeAction = GetWriter<object>(field, (f, w, o) => w.WriteEnum(f, o), true);
                 readAction = GetReader(field, MthdReadEnum);
             }
-            else if (genericDef == PortableUtils.TypGenericDictionary ||
-                type.GetInterface(PortableUtils.TypGenericDictionary.FullName) != null)
-            {
-                writeAction = GetWriter(field, MthdWriteGenericDictionary, type.GetGenericArguments());
-                readAction = GetReader(field, MthdReadGenericDictionary, type.GetGenericArguments());
-            }
-            else if (genericDef == PortableUtils.TypGenericCollection ||
-                type.GetInterface(PortableUtils.TypGenericCollection.FullName) != null)
-            {
-                writeAction = GetWriter(field, MthdWriteGenericCollection, type.GetGenericArguments());
-                readAction = GetReader(field, MthdReadGenericCollection, type.GetGenericArguments());
-            }
-            else if (type == PortableUtils.TypDictionary || type.GetInterface(PortableUtils.TypDictionary.FullName) != null)
+            else if (type == PortableUtils.TypDictionary || type.GetInterface(PortableUtils.TypDictionary.FullName) != null && !type.IsGenericType)
             {
                 writeAction = GetWriter<IDictionary>(field, (f, w, o) => w.WriteDictionary(f, o));
                 readAction = GetReader(field, (f, r) => r.ReadDictionary(f));
             }
-            else if (type == PortableUtils.TypCollection || type.GetInterface(PortableUtils.TypCollection.FullName) != null)
+            else if (type == PortableUtils.TypCollection || type.GetInterface(PortableUtils.TypCollection.FullName) != null && !type.IsGenericType)
             {
                 writeAction = GetWriter<ICollection>(field, (f, w, o) => w.WriteCollection(f, o));
                 readAction = GetReader(field, (f, r) => r.ReadCollection(f));