You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/09/04 18:27:48 UTC

[34/55] [abbrv] ignite git commit: IGNITE-1348: Moved GridGain's .Net module to Ignite.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
new file mode 100644
index 0000000..95a6ef8
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
@@ -0,0 +1,1336 @@
+/*
+ * 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;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Impl.Common;
+    using Apache.Ignite.Core.Impl.Portable.IO;
+
+    /// <summary>
+    /// Write delegate.
+    /// </summary>
+    /// <param name="writer">Write context.</param>
+    /// <param name="obj">Object to write.</param>
+    internal delegate void PortableSystemWriteDelegate(PortableWriterImpl writer, object obj);
+
+    /// <summary>
+    /// Typed write delegate.
+    /// </summary>
+    /// <param name="stream">Stream.</param>
+    /// <param name="obj">Object to write.</param>
+    // ReSharper disable once TypeParameterCanBeVariant
+    // Generic variance in a delegate causes performance hit
+    internal delegate void PortableSystemTypedWriteDelegate<T>(IPortableStream stream, T obj);
+
+    /**
+     * <summary>Collection of predefined handlers for various system types.</summary>
+     */
+    internal static class PortableSystemHandlers
+    {
+        /** Write handlers. */
+        private static readonly Dictionary<Type, PortableSystemWriteDelegate> WriteHandlers =
+            new Dictionary<Type, PortableSystemWriteDelegate>();
+
+        /** Read handlers. */
+        private static readonly IPortableSystemReader[] ReadHandlers = new IPortableSystemReader[255];
+
+        /** Typed write handler: boolean. */
+        public static readonly PortableSystemTypedWriteDelegate<bool> WriteHndBoolTyped = WriteBoolTyped;
+
+        /** Typed write handler: byte. */
+        public static readonly PortableSystemTypedWriteDelegate<byte> WriteHndByteTyped = WriteByteTyped;
+
+        /** Typed write handler: short. */
+        public static readonly PortableSystemTypedWriteDelegate<short> WriteHndShortTyped = WriteShortTyped;
+
+        /** Typed write handler: char. */
+        public static readonly PortableSystemTypedWriteDelegate<char> WriteHndCharTyped = WriteCharTyped;
+
+        /** Typed write handler: int. */
+        public static readonly PortableSystemTypedWriteDelegate<int> WriteHndIntTyped = WriteIntTyped;
+
+        /** Typed write handler: long. */
+        public static readonly PortableSystemTypedWriteDelegate<long> WriteHndLongTyped = WriteLongTyped;
+
+        /** Typed write handler: float. */
+        public static readonly PortableSystemTypedWriteDelegate<float> WriteHndFloatTyped = WriteFloatTyped;
+
+        /** Typed write handler: double. */
+        public static readonly PortableSystemTypedWriteDelegate<double> WriteHndDoubleTyped = WriteDoubleTyped;
+
+        /** Typed write handler: decimal. */
+        public static readonly PortableSystemTypedWriteDelegate<decimal> WriteHndDecimalTyped = WriteDecimalTyped;
+
+        /** Typed write handler: Date. */
+        public static readonly PortableSystemTypedWriteDelegate<DateTime?> WriteHndDateTyped = WriteDateTyped;
+
+        /** Typed write handler: string. */
+        public static readonly PortableSystemTypedWriteDelegate<string> WriteHndStringTyped = WriteStringTyped;
+
+        /** Typed write handler: Guid. */
+        public static readonly PortableSystemTypedWriteDelegate<Guid?> WriteHndGuidTyped = WriteGuidTyped;
+
+        /** Typed write handler: Portable. */
+        public static readonly PortableSystemTypedWriteDelegate<PortableUserObject> WriteHndPortableTyped = WritePortableTyped;
+
+        /** Typed write handler: boolean array. */
+        public static readonly PortableSystemTypedWriteDelegate<bool[]> WriteHndBoolArrayTyped = WriteBoolArrayTyped;
+
+        /** Typed write handler: byte array. */
+        public static readonly PortableSystemTypedWriteDelegate<byte[]> WriteHndByteArrayTyped = WriteByteArrayTyped;
+
+        /** Typed write handler: short array. */
+        public static readonly PortableSystemTypedWriteDelegate<short[]> WriteHndShortArrayTyped = WriteShortArrayTyped;
+
+        /** Typed write handler: char array. */
+        public static readonly PortableSystemTypedWriteDelegate<char[]> WriteHndCharArrayTyped = WriteCharArrayTyped;
+
+        /** Typed write handler: int array. */
+        public static readonly PortableSystemTypedWriteDelegate<int[]> WriteHndIntArrayTyped = WriteIntArrayTyped;
+
+        /** Typed write handler: long array. */
+        public static readonly PortableSystemTypedWriteDelegate<long[]> WriteHndLongArrayTyped = WriteLongArrayTyped;
+
+        /** Typed write handler: float array. */
+        public static readonly PortableSystemTypedWriteDelegate<float[]> WriteHndFloatArrayTyped = WriteFloatArrayTyped;
+
+        /** Typed write handler: double array. */
+        public static readonly PortableSystemTypedWriteDelegate<double[]> WriteHndDoubleArrayTyped = WriteDoubleArrayTyped;
+
+        /** Typed write handler: decimal array. */
+        public static readonly PortableSystemTypedWriteDelegate<decimal[]> WriteHndDecimalArrayTyped = WriteDecimalArrayTyped;
+
+        /** Typed write handler: Date array. */
+        public static readonly PortableSystemTypedWriteDelegate<DateTime?[]> WriteHndDateArrayTyped = WriteDateArrayTyped;
+
+        /** Typed write handler: string array. */
+        public static readonly PortableSystemTypedWriteDelegate<string[]> WriteHndStringArrayTyped = WriteStringArrayTyped;
+
+        /** Typed write handler: Guid array. */
+        public static readonly PortableSystemTypedWriteDelegate<Guid?[]> WriteHndGuidArrayTyped = WriteGuidArrayTyped;
+
+        /** Write handler: boolean. */
+        public static readonly PortableSystemWriteDelegate WriteHndBool = WriteBool;
+
+        /** Write handler: sbyte. */
+        public static readonly PortableSystemWriteDelegate WriteHndSbyte = WriteSbyte;
+
+        /** Write handler: byte. */
+        public static readonly PortableSystemWriteDelegate WriteHndByte = WriteByte;
+
+        /** Write handler: short. */
+        public static readonly PortableSystemWriteDelegate WriteHndShort = WriteShort;
+
+        /** Write handler: ushort. */
+        public static readonly PortableSystemWriteDelegate WriteHndUshort = WriteUshort;
+
+        /** Write handler: char. */
+        public static readonly PortableSystemWriteDelegate WriteHndChar = WriteChar;
+
+        /** Write handler: int. */
+        public static readonly PortableSystemWriteDelegate WriteHndInt = WriteInt;
+
+        /** Write handler: uint. */
+        public static readonly PortableSystemWriteDelegate WriteHndUint = WriteUint;
+
+        /** Write handler: long. */
+        public static readonly PortableSystemWriteDelegate WriteHndLong = WriteLong;
+
+        /** Write handler: ulong. */
+        public static readonly PortableSystemWriteDelegate WriteHndUlong = WriteUlong;
+
+        /** Write handler: float. */
+        public static readonly PortableSystemWriteDelegate WriteHndFloat = WriteFloat;
+
+        /** Write handler: double. */
+        public static readonly PortableSystemWriteDelegate WriteHndDouble = WriteDouble;
+
+        /** Write handler: decimal. */
+        public static readonly PortableSystemWriteDelegate WriteHndDecimal = WriteDecimal;
+
+        /** Write handler: Date. */
+        public static readonly PortableSystemWriteDelegate WriteHndDate = WriteDate;
+
+        /** Write handler: string. */
+        public static readonly PortableSystemWriteDelegate WriteHndString = WriteString;
+
+        /** Write handler: Guid. */
+        public static readonly PortableSystemWriteDelegate WriteHndGuid = WriteGuid;
+
+        /** Write handler: Portable. */
+        public static readonly PortableSystemWriteDelegate WriteHndPortable = WritePortable;
+
+        /** Write handler: Enum. */
+        public static readonly PortableSystemWriteDelegate WriteHndEnum = WriteEnum;
+
+        /** Write handler: boolean array. */
+        public static readonly PortableSystemWriteDelegate WriteHndBoolArray = WriteBoolArray;
+
+        /** Write handler: sbyte array. */
+        public static readonly PortableSystemWriteDelegate WriteHndSbyteArray = WriteSbyteArray;
+
+        /** Write handler: byte array. */
+        public static readonly PortableSystemWriteDelegate WriteHndByteArray = WriteByteArray;
+
+        /** Write handler: short array. */
+        public static readonly PortableSystemWriteDelegate WriteHndShortArray = WriteShortArray;
+
+        /** Write handler: ushort array. */
+        public static readonly PortableSystemWriteDelegate WriteHndUshortArray = WriteUshortArray;
+
+        /** Write handler: char array. */
+        public static readonly PortableSystemWriteDelegate WriteHndCharArray = WriteCharArray;
+
+        /** Write handler: int array. */
+        public static readonly PortableSystemWriteDelegate WriteHndIntArray = WriteIntArray;
+
+        /** Write handler: uint array. */
+        public static readonly PortableSystemWriteDelegate WriteHndUintArray = WriteUintArray;
+
+        /** Write handler: long array. */
+        public static readonly PortableSystemWriteDelegate WriteHndLongArray = WriteLongArray;
+
+        /** Write handler: ulong array. */
+        public static readonly PortableSystemWriteDelegate WriteHndUlongArray = WriteUlongArray;
+
+        /** Write handler: float array. */
+        public static readonly PortableSystemWriteDelegate WriteHndFloatArray = WriteFloatArray;
+
+        /** Write handler: double array. */
+        public static readonly PortableSystemWriteDelegate WriteHndDoubleArray = WriteDoubleArray;
+
+        /** Write handler: decimal array. */
+        public static readonly PortableSystemWriteDelegate WriteHndDecimalArray = WriteDecimalArray;
+
+        /** Write handler: date array. */
+        public static readonly PortableSystemWriteDelegate WriteHndDateArray = WriteDateArray;
+
+        /** Write handler: string array. */
+        public static readonly PortableSystemWriteDelegate WriteHndStringArray = WriteStringArray;
+
+        /** Write handler: Guid array. */
+        public static readonly PortableSystemWriteDelegate WriteHndGuidArray = WriteGuidArray;
+
+        /** Write handler: Enum array. */
+        public static readonly PortableSystemWriteDelegate WriteHndEnumArray = WriteEnumArray;
+
+        /** Write handler: object array. */
+        public static readonly PortableSystemWriteDelegate WriteHndArray = WriteArray;
+
+        /** Write handler: collection. */
+        public static readonly PortableSystemWriteDelegate WriteHndCollection = WriteCollection;
+
+        /** Write handler: dictionary. */
+        public static readonly PortableSystemWriteDelegate WriteHndDictionary = WriteDictionary;
+
+        /** Write handler: generic collection. */
+        public static readonly PortableSystemWriteDelegate WriteHndGenericCollection =
+            WriteGenericCollection;
+
+        /** Write handler: generic dictionary. */
+        public static readonly PortableSystemWriteDelegate WriteHndGenericDictionary =
+            WriteGenericDictionary;
+
+        /**
+         * <summary>Static initializer.</summary>
+         */
+        static PortableSystemHandlers()
+        {
+            // 1. Primitives.
+
+            ReadHandlers[PortableUtils.TypeBool] = new PortableSystemReader<bool>(s => s.ReadBool());
+
+            WriteHandlers[typeof(sbyte)] = WriteHndSbyte;
+            ReadHandlers[PortableUtils.TypeByte] = new PortableSystemReader<byte>(s => s.ReadByte());
+
+            WriteHandlers[typeof(ushort)] = WriteHndUshort;
+            ReadHandlers[PortableUtils.TypeShort] = new PortableSystemReader<short>(s => s.ReadShort());
+
+            ReadHandlers[PortableUtils.TypeChar] = new PortableSystemReader<char>(s => s.ReadChar());
+
+            WriteHandlers[typeof(uint)] = WriteHndUint;
+            ReadHandlers[PortableUtils.TypeInt] = new PortableSystemReader<int>(s => s.ReadInt());
+
+            WriteHandlers[typeof(ulong)] = WriteHndUlong;
+            ReadHandlers[PortableUtils.TypeLong] = new PortableSystemReader<long>(s => s.ReadLong());
+
+            ReadHandlers[PortableUtils.TypeFloat] = new PortableSystemReader<float>(s => s.ReadFloat());
+
+            ReadHandlers[PortableUtils.TypeDouble] = new PortableSystemReader<double>(s => s.ReadDouble());
+
+            ReadHandlers[PortableUtils.TypeDecimal] = new PortableSystemReader<decimal>(PortableUtils.ReadDecimal);
+
+            // 2. Date.
+            ReadHandlers[PortableUtils.TypeDate] =
+                new PortableSystemReader<DateTime?>(s => PortableUtils.ReadDate(s, false));
+
+            // 3. String.
+            ReadHandlers[PortableUtils.TypeString] = new PortableSystemReader<string>(PortableUtils.ReadString);
+
+            // 4. Guid.
+            ReadHandlers[PortableUtils.TypeGuid] = new PortableSystemReader<Guid?>(PortableUtils.ReadGuid);
+
+            // 5. Primitive arrays.
+            ReadHandlers[PortableUtils.TypeArrayBool] = new PortableSystemReader<bool[]>(PortableUtils.ReadBooleanArray);
+
+            WriteHandlers[typeof(sbyte[])] = WriteHndSbyteArray;
+            ReadHandlers[PortableUtils.TypeArrayByte] =
+                new PortableSystemDualReader<byte[], sbyte[]>(PortableUtils.ReadByteArray, PortableUtils.ReadSbyteArray);
+
+            WriteHandlers[typeof(ushort[])] = WriteHndUshortArray;
+            ReadHandlers[PortableUtils.TypeArrayShort] =
+                new PortableSystemDualReader<short[], ushort[]>(PortableUtils.ReadShortArray,
+                    PortableUtils.ReadUshortArray);
+
+            ReadHandlers[PortableUtils.TypeArrayChar] = 
+                new PortableSystemReader<char[]>(PortableUtils.ReadCharArray);
+
+            WriteHandlers[typeof(uint[])] = WriteHndUintArray;
+            ReadHandlers[PortableUtils.TypeArrayInt] =
+                new PortableSystemDualReader<int[], uint[]>(PortableUtils.ReadIntArray, PortableUtils.ReadUintArray);
+
+
+            WriteHandlers[typeof(ulong[])] = WriteHndUlongArray;
+            ReadHandlers[PortableUtils.TypeArrayLong] =
+                new PortableSystemDualReader<long[], ulong[]>(PortableUtils.ReadLongArray, 
+                    PortableUtils.ReadUlongArray);
+
+            ReadHandlers[PortableUtils.TypeArrayFloat] =
+                new PortableSystemReader<float[]>(PortableUtils.ReadFloatArray);
+
+            ReadHandlers[PortableUtils.TypeArrayDouble] =
+                new PortableSystemReader<double[]>(PortableUtils.ReadDoubleArray);
+
+            ReadHandlers[PortableUtils.TypeArrayDecimal] =
+                new PortableSystemReader<decimal[]>(PortableUtils.ReadDecimalArray);
+
+            // 6. Date array.
+            ReadHandlers[PortableUtils.TypeArrayDate] =
+                new PortableSystemReader<DateTime?[]>(s => PortableUtils.ReadDateArray(s, false));
+
+            // 7. String array.
+            ReadHandlers[PortableUtils.TypeArrayString] = new PortableSystemGenericArrayReader<string>();
+
+            // 8. Guid array.
+            ReadHandlers[PortableUtils.TypeArrayGuid] = new PortableSystemGenericArrayReader<Guid?>();
+
+            // 9. Array.
+            ReadHandlers[PortableUtils.TypeArray] = new PortableSystemReader(ReadArray);
+
+            // 10. Predefined collections.
+            WriteHandlers[typeof(ArrayList)] = WriteArrayList;
+
+            // 11. Predefined dictionaries.
+            WriteHandlers[typeof(Hashtable)] = WriteHashtable;
+
+            // 12. Arbitrary collection.
+            ReadHandlers[PortableUtils.TypeCollection] = new PortableSystemReader(ReadCollection);
+
+            // 13. Arbitrary dictionary.
+            ReadHandlers[PortableUtils.TypeDictionary] = new PortableSystemReader(ReadDictionary);
+
+            // 14. Map entry.
+            WriteHandlers[typeof(DictionaryEntry)] = WriteMapEntry;
+            ReadHandlers[PortableUtils.TypeMapEntry] = new PortableSystemReader(ReadMapEntry);
+
+            // 15. Portable.
+            WriteHandlers[typeof(PortableUserObject)] = WritePortable;
+
+            // 16. Enum.
+            ReadHandlers[PortableUtils.TypeEnum] = new PortableSystemReader<int>(PortableUtils.ReadEnum<int>);
+            ReadHandlers[PortableUtils.TypeArrayEnum] = new PortableSystemReader(ReadEnumArray);
+        }
+
+        /**
+         * <summary>Get write handler for type.</summary>
+         * <param name="type">Type.</param>
+         * <returns>Handler or null if cannot be hanled in special way.</returns>
+         */
+        public static PortableSystemWriteDelegate WriteHandler(Type type)
+        {
+            PortableSystemWriteDelegate handler;
+
+            if (WriteHandlers.TryGetValue(type, out handler))
+                return handler;
+
+            // 1. Array?
+            if (type.IsArray)
+            {
+                if (type.GetElementType().IsEnum)
+                    return WriteEnumArray;
+                return WriteArray;
+            }
+
+            // 2. Enum?
+            if (type.IsEnum)
+                return WriteEnum;
+
+            // 3. Collection?
+            PortableCollectionInfo info = PortableCollectionInfo.Info(type);
+
+            if (info.IsAny)
+                return info.WriteHandler;
+
+            // No special handler found.
+            return null;
+        }
+
+        /// <summary>
+        /// Reads an object of predefined type.
+        /// </summary>
+        public static T ReadSystemType<T>(byte typeId, PortableReaderImpl ctx)
+        {
+            var handler = ReadHandlers[typeId];
+
+            Debug.Assert(handler != null, "Cannot find predefined read handler: " + typeId);
+            
+            return handler.Read<T>(ctx);
+        }
+
+        /**
+         * <summary>Write boolean.</summary>
+         */
+        private static void WriteBool(PortableWriterImpl ctx, object obj)
+        {
+            WriteBoolTyped(ctx.Stream, (bool)obj);
+        }
+
+        /**
+         * <summary>Write boolean.</summary>
+         */
+        private static void WriteBoolTyped(IPortableStream stream, bool obj)
+        {
+            stream.WriteByte(PortableUtils.TypeBool);
+
+            stream.WriteBool(obj);
+        }
+
+        /**
+         * <summary>Write sbyte.</summary>
+         */
+        private static unsafe void WriteSbyte(PortableWriterImpl ctx, object obj)
+        {
+            sbyte val = (sbyte)obj;
+
+            ctx.Stream.WriteByte(PortableUtils.TypeByte);
+            ctx.Stream.WriteByte(*(byte*)&val);
+        }
+
+        /**
+         * <summary>Write byte.</summary>
+         */
+        private static void WriteByte(PortableWriterImpl ctx, object obj)
+        {
+            WriteByteTyped(ctx.Stream, (byte)obj);
+        }
+
+        /**
+         * <summary>Write byte.</summary>
+         */
+        private static void WriteByteTyped(IPortableStream stream, byte obj)
+        {
+            stream.WriteByte(PortableUtils.TypeByte);
+            stream.WriteByte(obj);
+        }
+
+        /**
+         * <summary>Write short.</summary>
+         */
+        private static void WriteShort(PortableWriterImpl ctx, object obj)
+        {
+            WriteShortTyped(ctx.Stream, (short)obj);
+        }
+
+        /**
+         * <summary>Write short.</summary>
+         */
+        private static void WriteShortTyped(IPortableStream stream, short obj)
+        {
+            stream.WriteByte(PortableUtils.TypeShort);
+
+            stream.WriteShort(obj);
+        }
+
+        /**
+         * <summary>Write ushort.</summary>
+         */
+        private static unsafe void WriteUshort(PortableWriterImpl ctx, object obj)
+        {
+            ushort val = (ushort)obj;
+
+            ctx.Stream.WriteByte(PortableUtils.TypeShort);
+
+            ctx.Stream.WriteShort(*(short*)&val);
+        }
+
+        /**
+         * <summary>Write char.</summary>
+         */
+        private static void WriteChar(PortableWriterImpl ctx, object obj)
+        {
+            WriteCharTyped(ctx.Stream, (char)obj);
+        }
+
+        /**
+         * <summary>Write char.</summary>
+         */
+        private static void WriteCharTyped(IPortableStream stream, char obj)
+        {
+            stream.WriteByte(PortableUtils.TypeChar);
+
+            stream.WriteChar(obj);
+        }
+
+        /**
+         * <summary>Write int.</summary>
+         */
+        private static void WriteInt(PortableWriterImpl ctx, object obj)
+        {
+            WriteIntTyped(ctx.Stream, (int)obj);
+        }
+
+        /**
+         * <summary>Write int.</summary>
+         */
+        private static void WriteIntTyped(IPortableStream stream, int obj)
+        {
+            stream.WriteByte(PortableUtils.TypeInt);
+            stream.WriteInt(obj);
+        }
+
+        /**
+         * <summary>Write uint.</summary>
+         */
+        private static unsafe void WriteUint(PortableWriterImpl ctx, object obj)
+        {
+            uint val = (uint)obj;
+
+            ctx.Stream.WriteByte(PortableUtils.TypeInt);
+            ctx.Stream.WriteInt(*(int*)&val);
+        }
+
+        /**
+         * <summary>Write long.</summary>
+         */
+        private static void WriteLong(PortableWriterImpl ctx, object obj)
+        {
+            WriteLongTyped(ctx.Stream, (long)obj);
+        }
+
+        /**
+         * <summary>Write long.</summary>
+         */
+        private static void WriteLongTyped(IPortableStream stream, long obj)
+        {
+            stream.WriteByte(PortableUtils.TypeLong);
+            stream.WriteLong(obj);
+        }
+
+        /**
+         * <summary>Write ulong.</summary>
+         */
+        private static unsafe void WriteUlong(PortableWriterImpl ctx, object obj)
+        {
+            ulong val = (ulong)obj;
+
+            ctx.Stream.WriteByte(PortableUtils.TypeLong);
+            ctx.Stream.WriteLong(*(long*)&val);
+        }
+
+        /**
+         * <summary>Write float.</summary>
+         */
+        private static void WriteFloat(PortableWriterImpl ctx, object obj)
+        {
+            WriteFloatTyped(ctx.Stream, (float)obj);
+        }
+
+        /**
+         * <summary>Write float.</summary>
+         */
+        private static void WriteFloatTyped(IPortableStream stream, float obj)
+        {
+            stream.WriteByte(PortableUtils.TypeFloat);
+            stream.WriteFloat(obj);
+        }
+
+        /**
+         * <summary>Write double.</summary>
+         */
+        private static void WriteDouble(PortableWriterImpl ctx, object obj)
+        {
+            WriteDoubleTyped(ctx.Stream, (double)obj);
+        }
+
+        /**
+         * <summary>Write double.</summary>
+         */
+        private static void WriteDoubleTyped(IPortableStream stream, double obj)
+        {
+            stream.WriteByte(PortableUtils.TypeDouble);
+            stream.WriteDouble(obj);
+        }
+
+        /**
+         * <summary>Write decimal.</summary>
+         */
+        private static void WriteDecimal(PortableWriterImpl ctx, object obj)
+        {
+            WriteDecimalTyped(ctx.Stream, (decimal)obj);
+        }
+
+        /**
+         * <summary>Write double.</summary>
+         */
+        private static void WriteDecimalTyped(IPortableStream stream, decimal obj)
+        {
+            stream.WriteByte(PortableUtils.TypeDecimal);
+
+            PortableUtils.WriteDecimal(obj, stream);
+        }
+
+        /**
+         * <summary>Write date.</summary>
+         */
+        private static void WriteDate(PortableWriterImpl ctx, object obj)
+        {
+            WriteDateTyped(ctx.Stream, (DateTime?)obj);
+        }
+
+        /**
+         * <summary>Write double.</summary>
+         */
+        private static void WriteDateTyped(IPortableStream stream, DateTime? obj)
+        {
+            stream.WriteByte(PortableUtils.TypeDate);
+
+            PortableUtils.WriteDate(obj, stream);
+        }
+
+        /**
+         * <summary>Write string.</summary>
+         */
+        private static void WriteString(PortableWriterImpl ctx, object obj)
+        {
+            WriteStringTyped(ctx.Stream, (string)obj);
+        }
+
+        /**
+         * <summary>Write string.</summary>
+         */
+        private static void WriteStringTyped(IPortableStream stream, string obj)
+        {
+            stream.WriteByte(PortableUtils.TypeString);
+
+            PortableUtils.WriteString(obj, stream);
+        }
+
+        /**
+         * <summary>Write Guid.</summary>
+         */
+        private static void WriteGuid(PortableWriterImpl ctx, object obj)
+        {
+            WriteGuidTyped(ctx.Stream, (Guid?)obj);
+        }
+
+        /**
+         * <summary>Write Guid.</summary>
+         */
+        private static void WriteGuidTyped(IPortableStream stream, Guid? obj)
+        {
+            stream.WriteByte(PortableUtils.TypeGuid);
+
+            PortableUtils.WriteGuid(obj, stream);
+        }
+
+        /**
+         * <summary>Write bool array.</summary>
+         */
+        private static void WriteBoolArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteBoolArrayTyped(ctx.Stream, (bool[])obj);
+        }
+
+        /**
+         * <summary>Write bool array.</summary>
+         */
+        private static void WriteBoolArrayTyped(IPortableStream stream, bool[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayBool);
+
+            PortableUtils.WriteBooleanArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write byte array.</summary>
+         */
+        private static void WriteByteArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteByteArrayTyped(ctx.Stream, (byte[])obj);
+        }
+
+        /**
+         * <summary>Write byte array.</summary>
+         */
+        private static void WriteByteArrayTyped(IPortableStream stream, byte[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayByte);
+
+            PortableUtils.WriteByteArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write sbyte array.</summary>
+         */
+        private static void WriteSbyteArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayByte);
+
+            PortableUtils.WriteByteArray((byte[])(Array)obj, ctx.Stream);
+        }
+
+        /**
+         * <summary>Write short array.</summary>
+         */
+        private static void WriteShortArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteShortArrayTyped(ctx.Stream, (short[])obj);
+        }
+
+        /**
+         * <summary>Write short array.</summary>
+         */
+        private static void WriteShortArrayTyped(IPortableStream stream, short[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayShort);
+
+            PortableUtils.WriteShortArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write ushort array.</summary>
+         */
+        private static void WriteUshortArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayShort);
+
+            PortableUtils.WriteShortArray((short[])(Array)obj, ctx.Stream);
+        }
+
+        /**
+         * <summary>Write char array.</summary>
+         */
+        private static void WriteCharArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteCharArrayTyped(ctx.Stream, (char[])obj);
+        }
+
+        /**
+         * <summary>Write char array.</summary>
+         */
+        private static void WriteCharArrayTyped(IPortableStream stream, char[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayChar);
+
+            PortableUtils.WriteCharArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write int array.</summary>
+         */
+        private static void WriteIntArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteIntArrayTyped(ctx.Stream, (int[])obj);
+        }
+
+        /**
+         * <summary>Write int array.</summary>
+         */
+        private static void WriteIntArrayTyped(IPortableStream stream, int[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayInt);
+
+            PortableUtils.WriteIntArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write uint array.</summary>
+         */
+        private static void WriteUintArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayInt);
+
+            PortableUtils.WriteIntArray((int[])(Array)obj, ctx.Stream);
+        }
+
+        /**
+         * <summary>Write long array.</summary>
+         */
+        private static void WriteLongArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteLongArrayTyped(ctx.Stream, (long[])obj);
+        }
+
+        /**
+         * <summary>Write long array.</summary>
+         */
+        private static void WriteLongArrayTyped(IPortableStream stream, long[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayLong);
+
+            PortableUtils.WriteLongArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write ulong array.</summary>
+         */
+        private static void WriteUlongArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayLong);
+
+            PortableUtils.WriteLongArray((long[])(Array)obj, ctx.Stream);
+        }
+
+        /**
+         * <summary>Write float array.</summary>
+         */
+        private static void WriteFloatArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteFloatArrayTyped(ctx.Stream, (float[])obj);
+        }
+
+        /**
+         * <summary>Write float array.</summary>
+         */
+        private static void WriteFloatArrayTyped(IPortableStream stream, float[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayFloat);
+
+            PortableUtils.WriteFloatArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write double array.</summary>
+         */
+        private static void WriteDoubleArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteDoubleArrayTyped(ctx.Stream, (double[])obj);
+        }
+
+        /**
+         * <summary>Write double array.</summary>
+         */
+        private static void WriteDoubleArrayTyped(IPortableStream stream, double[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayDouble);
+
+            PortableUtils.WriteDoubleArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write decimal array.</summary>
+         */
+        private static void WriteDecimalArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteDecimalArrayTyped(ctx.Stream, (decimal[])obj);
+        }
+
+        /**
+         * <summary>Write double array.</summary>
+         */
+        private static void WriteDecimalArrayTyped(IPortableStream stream, decimal[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayDecimal);
+
+            PortableUtils.WriteDecimalArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write date array.</summary>
+         */
+        private static void WriteDateArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteDateArrayTyped(ctx.Stream, (DateTime?[])obj);
+        }
+
+        /**
+         * <summary>Write date array.</summary>
+         */
+        private static void WriteDateArrayTyped(IPortableStream stream, DateTime?[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayDate);
+
+            PortableUtils.WriteDateArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write string array.</summary>
+         */
+        private static void WriteStringArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteStringArrayTyped(ctx.Stream, (string[])obj);
+        }
+
+        /**
+         * <summary>Write string array.</summary>
+         */
+        private static void WriteStringArrayTyped(IPortableStream stream, string[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayString);
+
+            PortableUtils.WriteStringArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write Guid array.</summary>
+         */
+        private static void WriteGuidArray(PortableWriterImpl ctx, object obj)
+        {
+            WriteGuidArrayTyped(ctx.Stream, (Guid?[])obj);
+        }
+
+        /**
+         * <summary>Write Guid array.</summary>
+         */
+        private static void WriteGuidArrayTyped(IPortableStream stream, Guid?[] obj)
+        {
+            stream.WriteByte(PortableUtils.TypeArrayGuid);
+
+            PortableUtils.WriteGuidArray(obj, stream);
+        }
+
+        /**
+         * <summary>Write enum array.</summary>
+         */
+        private static void WriteEnumArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayEnum);
+
+            PortableUtils.WriteArray((Array)obj, ctx, true);
+        }
+
+        /**
+         * <summary>Write array.</summary>
+         */
+        private static void WriteArray(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeArray);
+
+            PortableUtils.WriteArray((Array)obj, ctx, true);
+        }
+
+        /**
+         * <summary>Write collection.</summary>
+         */
+        private static void WriteCollection(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeCollection);
+
+            PortableUtils.WriteCollection((ICollection)obj, ctx);
+        }
+
+        /**
+         * <summary>Write generic collection.</summary>
+         */
+        private static void WriteGenericCollection(PortableWriterImpl ctx, object obj)
+        {
+            PortableCollectionInfo info = PortableCollectionInfo.Info(obj.GetType());
+
+            Debug.Assert(info.IsGenericCollection, "Not generic collection: " + obj.GetType().FullName);
+
+            ctx.Stream.WriteByte(PortableUtils.TypeCollection);
+
+            info.WriteGeneric(ctx, obj);
+        }
+
+        /**
+         * <summary>Write dictionary.</summary>
+         */
+        private static void WriteDictionary(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeDictionary);
+
+            PortableUtils.WriteDictionary((IDictionary)obj, ctx);
+        }
+
+        /**
+         * <summary>Write generic dictionary.</summary>
+         */
+        private static void WriteGenericDictionary(PortableWriterImpl ctx, object obj)
+        {
+            PortableCollectionInfo info = PortableCollectionInfo.Info(obj.GetType());
+
+            Debug.Assert(info.IsGenericDictionary, "Not generic dictionary: " + obj.GetType().FullName);
+
+            ctx.Stream.WriteByte(PortableUtils.TypeDictionary);
+
+            info.WriteGeneric(ctx, obj);
+        }
+
+        /**
+         * <summary>Write ArrayList.</summary>
+         */
+        private static void WriteArrayList(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeCollection);
+
+            PortableUtils.WriteTypedCollection((ICollection)obj, ctx, PortableUtils.CollectionArrayList);
+        }
+
+        /**
+         * <summary>Write Hashtable.</summary>
+         */
+        private static void WriteHashtable(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeDictionary);
+
+            PortableUtils.WriteTypedDictionary((IDictionary)obj, ctx, PortableUtils.MapHashMap);
+        }
+
+        /**
+         * <summary>Write map entry.</summary>
+         */
+        private static void WriteMapEntry(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeMapEntry);
+
+            PortableUtils.WriteMapEntry(ctx, (DictionaryEntry)obj);
+        }
+
+        /**
+         * <summary>Write portable object.</summary>
+         */
+        private static void WritePortable(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypePortable);
+
+            PortableUtils.WritePortable(ctx.Stream, (PortableUserObject)obj);
+        }
+
+        /**
+         * <summary>Write portable object.</summary>
+         */
+        private static void WritePortableTyped(IPortableStream stream, PortableUserObject obj)
+        {
+            stream.WriteByte(PortableUtils.TypePortable);
+
+            PortableUtils.WritePortable(stream, obj);
+        }
+
+        /// <summary>
+        /// Write enum.
+        /// </summary>
+        private static void WriteEnum(PortableWriterImpl ctx, object obj)
+        {
+            ctx.Stream.WriteByte(PortableUtils.TypeEnum);
+
+            PortableUtils.WriteEnum(ctx.Stream, (Enum)obj);
+        }
+
+        /**
+         * <summary>Read enum array.</summary>
+         */
+        private static object ReadEnumArray(PortableReaderImpl ctx, Type type)
+        {
+            return PortableUtils.ReadArray(ctx, true, type.GetElementType());
+        }
+
+        /**
+         * <summary>Read array.</summary>
+         */
+        private static object ReadArray(PortableReaderImpl ctx, Type type)
+        {
+            var elemType = type.IsArray ? type.GetElementType() : typeof(object);
+
+            return PortableUtils.ReadArray(ctx, true, elemType);
+        }
+
+        /**
+         * <summary>Read collection.</summary>
+         */
+        private static object ReadCollection(PortableReaderImpl ctx, Type type)
+        {
+            PortableCollectionInfo info = PortableCollectionInfo.Info(type);
+
+            return info.IsGenericCollection 
+                ? info.ReadGeneric(ctx)
+                : PortableUtils.ReadCollection(ctx, null, null);
+        }
+
+        /**
+         * <summary>Read dictionary.</summary>
+         */
+        private static object ReadDictionary(PortableReaderImpl ctx, Type type)
+        {
+            PortableCollectionInfo info = PortableCollectionInfo.Info(type);
+
+            return info.IsGenericDictionary
+                ? info.ReadGeneric(ctx)
+                : PortableUtils.ReadDictionary(ctx, null);
+        }
+
+        /**
+         * <summary>Read map entry.</summary>
+         */
+        private static object ReadMapEntry(PortableReaderImpl ctx, Type type)
+        {
+            return PortableUtils.ReadMapEntry(ctx);
+        }
+
+        /**
+         * <summary>Create new ArrayList.</summary>
+         * <param name="len">Length.</param>
+         * <returns>ArrayList.</returns>
+         */
+        public static ICollection CreateArrayList(int len)
+        {
+            return new ArrayList(len);
+        }
+
+        /**
+         * <summary>Add element to array list.</summary>
+         * <param name="col">Array list.</param>
+         * <param name="elem">Element.</param>
+         */
+        public static void AddToArrayList(ICollection col, object elem)
+        {
+            ((ArrayList) col).Add(elem);
+        }
+
+        /**
+         * <summary>Create new List.</summary>
+         * <param name="len">Length.</param>
+         * <returns>List.</returns>
+         */
+        public static ICollection<T> CreateList<T>(int len)
+        {
+            return new List<T>(len);
+        }
+
+        /**
+         * <summary>Create new LinkedList.</summary>
+         * <param name="len">Length.</param>
+         * <returns>LinkedList.</returns>
+         */
+        public static ICollection<T> CreateLinkedList<T>(int len)
+        {
+            return new LinkedList<T>();
+        }
+
+        /**
+         * <summary>Create new HashSet.</summary>
+         * <param name="len">Length.</param>
+         * <returns>HashSet.</returns>
+         */
+        public static ICollection<T> CreateHashSet<T>(int len)
+        {
+            return new HashSet<T>();
+        }
+
+        /**
+         * <summary>Create new SortedSet.</summary>
+         * <param name="len">Length.</param>
+         * <returns>SortedSet.</returns>
+         */
+        public static ICollection<T> CreateSortedSet<T>(int len)
+        {
+            return new SortedSet<T>();
+        }
+
+        /**
+         * <summary>Create new Hashtable.</summary>
+         * <param name="len">Length.</param>
+         * <returns>Hashtable.</returns>
+         */
+        public static IDictionary CreateHashtable(int len)
+        {
+            return new Hashtable(len);
+        }
+
+        /**
+         * <summary>Create new Dictionary.</summary>
+         * <param name="len">Length.</param>
+         * <returns>Dictionary.</returns>
+         */
+        public static IDictionary<TK, TV> CreateDictionary<TK, TV>(int len)
+        {
+            return new Dictionary<TK, TV>(len);
+        }
+
+        /**
+         * <summary>Create new SortedDictionary.</summary>
+         * <param name="len">Length.</param>
+         * <returns>SortedDictionary.</returns>
+         */
+        public static IDictionary<TK, TV> CreateSortedDictionary<TK, TV>(int len)
+        {
+            return new SortedDictionary<TK, TV>();
+        }
+
+        /**
+         * <summary>Create new ConcurrentDictionary.</summary>
+         * <param name="len">Length.</param>
+         * <returns>ConcurrentDictionary.</returns>
+         */
+        public static IDictionary<TK, TV> CreateConcurrentDictionary<TK, TV>(int len)
+        {
+            return new ConcurrentDictionary<TK, TV>(Environment.ProcessorCount, len);
+        }
+
+
+        /**
+         * <summary>Read delegate.</summary>
+         * <param name="ctx">Read context.</param>
+         * <param name="type">Type.</param>
+         */
+        private delegate object PortableSystemReadDelegate(PortableReaderImpl ctx, Type type);
+
+        /// <summary>
+        /// System type reader.
+        /// </summary>
+        private interface IPortableSystemReader
+        {
+            /// <summary>
+            /// Reads a value of specified type from reader.
+            /// </summary>
+            T Read<T>(PortableReaderImpl ctx);
+        }
+
+        /// <summary>
+        /// System type generic reader.
+        /// </summary>
+        private interface IPortableSystemReader<out T>
+        {
+            /// <summary>
+            /// Reads a value of specified type from reader.
+            /// </summary>
+            T Read(PortableReaderImpl ctx);
+        }
+
+        /// <summary>
+        /// Default reader with boxing.
+        /// </summary>
+        private class PortableSystemReader : IPortableSystemReader
+        {
+            /** */
+            private readonly PortableSystemReadDelegate _readDelegate;
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="PortableSystemReader"/> class.
+            /// </summary>
+            /// <param name="readDelegate">The read delegate.</param>
+            public PortableSystemReader(PortableSystemReadDelegate readDelegate)
+            {
+                Debug.Assert(readDelegate != null);
+
+                _readDelegate = readDelegate;
+            }
+
+            /** <inheritdoc /> */
+            public T Read<T>(PortableReaderImpl ctx)
+            {
+                return (T)_readDelegate(ctx, typeof(T));
+            }
+        }
+
+        /// <summary>
+        /// Reader without boxing.
+        /// </summary>
+        private class PortableSystemReader<T> : IPortableSystemReader
+        {
+            /** */
+            private readonly Func<IPortableStream, T> _readDelegate;
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="PortableSystemReader{T}"/> class.
+            /// </summary>
+            /// <param name="readDelegate">The read delegate.</param>
+            public PortableSystemReader(Func<IPortableStream, T> readDelegate)
+            {
+                Debug.Assert(readDelegate != null);
+
+                _readDelegate = readDelegate;
+            }
+
+            /** <inheritdoc /> */
+            public TResult Read<TResult>(PortableReaderImpl ctx)
+            {
+                return TypeCaster<TResult>.Cast(_readDelegate(ctx.Stream));
+            }
+        }
+
+        /// <summary>
+        /// Reader without boxing.
+        /// </summary>
+        private class PortableSystemGenericArrayReader<T> : IPortableSystemReader
+        {
+            public TResult Read<TResult>(PortableReaderImpl ctx)
+            {
+                return TypeCaster<TResult>.Cast(PortableUtils.ReadGenericArray<T>(ctx, false));
+            }
+        }
+
+        /// <summary>
+        /// Reader with selection based on requested type.
+        /// </summary>
+        private class PortableSystemDualReader<T1, T2> : IPortableSystemReader, IPortableSystemReader<T2>
+        {
+            /** */
+            private readonly Func<IPortableStream, T1> _readDelegate1;
+
+            /** */
+            private readonly Func<IPortableStream, T2> _readDelegate2;
+
+            /// <summary>
+            /// Initializes a new instance of the <see cref="PortableSystemDualReader{T1, T2}"/> class.
+            /// </summary>
+            /// <param name="readDelegate1">The read delegate1.</param>
+            /// <param name="readDelegate2">The read delegate2.</param>
+            public PortableSystemDualReader(Func<IPortableStream, T1> readDelegate1, Func<IPortableStream, T2> readDelegate2)
+            {
+                Debug.Assert(readDelegate1 != null);
+                Debug.Assert(readDelegate2 != null);
+
+                _readDelegate1 = readDelegate1;
+                _readDelegate2 = readDelegate2;
+            }
+
+            /** <inheritdoc /> */
+            T2 IPortableSystemReader<T2>.Read(PortableReaderImpl ctx)
+            {
+                return _readDelegate2(ctx.Stream);
+            }
+
+            /** <inheritdoc /> */
+            public T Read<T>(PortableReaderImpl ctx)
+            {
+                // Can't use "as" because of variance. 
+                // For example, IPortableSystemReader<byte[]> can be cast to IPortableSystemReader<sbyte[]>, which
+                // will cause incorrect behavior.
+                if (typeof (T) == typeof (T2))  
+                    return ((IPortableSystemReader<T>) this).Read(ctx);
+
+                return TypeCaster<T>.Cast(_readDelegate1(ctx.Stream));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemTypeSerializer.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemTypeSerializer.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemTypeSerializer.cs
new file mode 100644
index 0000000..014955b
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemTypeSerializer.cs
@@ -0,0 +1,62 @@
+/*
+ * 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.Diagnostics;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// Portable serializer for system types.
+    /// </summary>
+    /// <typeparam name="T">Object type.</typeparam>
+    internal class PortableSystemTypeSerializer<T> : IPortableSystemTypeSerializer where T : IPortableWriteAware
+    {
+        /** Ctor delegate. */
+        private readonly Func<PortableReaderImpl, T> _ctor;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PortableSystemTypeSerializer{T}"/> class.
+        /// </summary>
+        /// <param name="ctor">Constructor delegate.</param>
+        public PortableSystemTypeSerializer(Func<PortableReaderImpl, T> ctor)
+        {
+            Debug.Assert(ctor != null);
+
+            _ctor = ctor;
+        }
+
+        /** <inheritdoc /> */
+        public void WritePortable(object obj, IPortableWriter writer)
+        {
+            ((T) obj).WritePortable(writer);
+        }
+
+        /** <inheritdoc /> */
+        public void ReadPortable(object obj, IPortableReader reader)
+        {
+            throw new NotSupportedException("System serializer does not support ReadPortable.");
+        }
+
+        /** <inheritdoc /> */
+        public object ReadInstance(PortableReaderImpl reader)
+        {
+            return _ctor(reader);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
new file mode 100644
index 0000000..3ca8a5f
--- /dev/null
+++ b/modules/platform/src/main/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
@@ -0,0 +1,385 @@
+/*
+ * 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;
+    using System.Collections.Generic;
+    using System.IO;
+    using System.Runtime.CompilerServices;
+    using System.Text;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Portable.IO;
+    using Apache.Ignite.Core.Portable;
+
+    /// <summary>
+    /// User portable object.
+    /// </summary>
+    internal class PortableUserObject : IPortableObject
+    {
+        /** Marshaller. */
+        private readonly PortableMarshaller _marsh;
+
+        /** Raw data of this portable object. */
+        private readonly byte[] _data;
+
+        /** Offset in data array. */
+        private readonly int _offset;
+
+        /** Type ID. */
+        private readonly int _typeId;
+
+        /** Hash code. */
+        private readonly int _hashCode;
+
+        /** Fields. */
+        private volatile IDictionary<int, int> _fields;
+
+        /** Deserialized value. */
+        private object _deserialized;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PortableUserObject"/> class.
+        /// </summary>
+        /// <param name="marsh">Marshaller.</param>
+        /// <param name="data">Raw data of this portable object.</param>
+        /// <param name="offset">Offset in data array.</param>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="hashCode">Hash code.</param>
+        public PortableUserObject(PortableMarshaller marsh, byte[] data, int offset, int typeId, int hashCode)
+        {
+            _marsh = marsh;
+
+            _data = data;
+            _offset = offset;
+
+            _typeId = typeId;
+            _hashCode = hashCode;
+        }
+
+        /** <inheritdoc /> */
+        public int TypeId()
+        {
+            return _typeId;
+        }
+
+        /** <inheritdoc /> */
+        public T Field<T>(string fieldName)
+        {
+            return Field<T>(fieldName, null);
+        }
+
+        /** <inheritdoc /> */
+        public T Deserialize<T>()
+        {
+            return Deserialize<T>(PortableMode.Deserialize);
+        }
+
+        /// <summary>
+        /// Internal deserialization routine.
+        /// </summary>
+        /// <param name="mode">The mode.</param>
+        /// <returns>
+        /// Deserialized object.
+        /// </returns>
+        private T Deserialize<T>(PortableMode mode)
+        {
+            if (_deserialized == null)
+            {
+                IPortableStream stream = new PortableHeapStream(_data);
+
+                stream.Seek(_offset, SeekOrigin.Begin);
+
+                T res = _marsh.Unmarshal<T>(stream, mode);
+
+                IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId);
+
+                if (!desc.KeepDeserialized)
+                    return res;
+
+                _deserialized = res;
+            }
+
+            return (T)_deserialized;
+        }
+
+        /** <inheritdoc /> */
+        public IPortableMetadata Metadata()
+        {
+            return _marsh.Metadata(_typeId);
+        }
+
+        /// <summary>
+        /// Raw data of this portable object.
+        /// </summary>
+        public byte[] Data
+        {
+            get { return _data; }
+        }
+
+        /// <summary>
+        /// Offset in data array.
+        /// </summary>
+        public int Offset
+        {
+            get { return _offset; }
+        }
+
+        /// <summary>
+        /// Get field with builder.
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="fieldName"></param>
+        /// <param name="builder"></param>
+        /// <returns></returns>
+        public T Field<T>(string fieldName, PortableBuilderImpl builder)
+        {
+            IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId);
+
+            InitializeFields();
+
+            int fieldId = PortableUtils.FieldId(_typeId, fieldName, desc.NameConverter, desc.Mapper);
+
+            int pos;
+
+            if (_fields.TryGetValue(fieldId, out pos))
+            {
+                if (builder != null)
+                {
+                    // Read in scope of build process.
+                    T res;
+
+                    if (!builder.CachedField(pos, out res))
+                    {
+                        res = Field0<T>(pos, builder);
+
+                        builder.CacheField(pos, res);
+                    }
+
+                    return res;
+                }
+                return Field0<T>(pos, null);
+            }
+            return default(T);
+        }
+
+        /// <summary>
+        /// Lazy fields initialization routine.
+        /// </summary>
+        private void InitializeFields()
+        {
+            if (_fields == null)
+            {
+                IPortableStream stream = new PortableHeapStream(_data);
+
+                stream.Seek(_offset + 14, SeekOrigin.Begin);
+
+                int rawDataOffset = stream.ReadInt();
+
+                _fields = PortableUtils.ObjectFields(stream, _typeId, rawDataOffset);
+            }
+        }
+
+        /// <summary>
+        /// Gets field value on the given object.
+        /// </summary>
+        /// <param name="pos">Position.</param>
+        /// <param name="builder">Builder.</param>
+        /// <returns>Field value.</returns>
+        private T Field0<T>(int pos, PortableBuilderImpl builder)
+        {
+            IPortableStream stream = new PortableHeapStream(_data);
+
+            stream.Seek(pos, SeekOrigin.Begin);
+
+            return _marsh.Unmarshal<T>(stream, PortableMode.ForcePortable, builder);
+        }
+
+        /** <inheritdoc /> */
+        public override int GetHashCode()
+        {
+            return _hashCode;
+        }
+
+        /** <inheritdoc /> */
+        public override bool Equals(object obj)
+        {
+            if (this == obj)
+                return true;
+
+            PortableUserObject that = obj as PortableUserObject;
+
+            if (that != null)
+            {
+                if (_data == that._data && _offset == that._offset)
+                    return true;
+
+                // 1. Check hash code and type IDs.
+                if (_hashCode == that._hashCode && _typeId == that._typeId)
+                {
+                    // 2. Check if objects have the same field sets.
+                    InitializeFields();
+                    that.InitializeFields();
+
+                    if (_fields.Keys.Count != that._fields.Keys.Count)
+                        return false;
+
+                    foreach (int id in _fields.Keys)
+                    {
+                        if (!that._fields.Keys.Contains(id))
+                            return false;
+                    }
+
+                    // 3. Check if objects have the same field values.
+                    foreach (KeyValuePair<int, int> field in _fields)
+                    {
+                        object fieldVal = Field0<object>(field.Value, null);
+                        object thatFieldVal = that.Field0<object>(that._fields[field.Key], null);
+
+                        if (!Equals(fieldVal, thatFieldVal))
+                            return false;
+                    }
+
+                    // 4. Check if objects have the same raw data.
+                    IPortableStream stream = new PortableHeapStream(_data);
+                    stream.Seek(_offset + 10, SeekOrigin.Begin);
+                    int len = stream.ReadInt();
+                    int rawOffset = stream.ReadInt();
+
+                    IPortableStream thatStream = new PortableHeapStream(that._data);
+                    thatStream.Seek(_offset + 10, SeekOrigin.Begin);
+                    int thatLen = thatStream.ReadInt();
+                    int thatRawOffset = thatStream.ReadInt();
+
+                    return PortableUtils.CompareArrays(_data, _offset + rawOffset, len - rawOffset, that._data,
+                        that._offset + thatRawOffset, thatLen - thatRawOffset);
+                }
+            }
+
+            return false;
+        }
+
+        /** <inheritdoc /> */
+        public override string ToString()
+        {
+            return ToString(new Dictionary<int, int>());            
+        }
+
+        /// <summary>
+        /// ToString implementation.
+        /// </summary>
+        /// <param name="handled">Already handled objects.</param>
+        /// <returns>Object string.</returns>
+        private string ToString(IDictionary<int, int> handled)
+        {
+            int idHash;
+
+            bool alreadyHandled = handled.TryGetValue(_offset, out idHash);
+
+            if (!alreadyHandled)
+                idHash = RuntimeHelpers.GetHashCode(this);
+
+            StringBuilder sb;
+
+            IPortableTypeDescriptor desc = _marsh.Descriptor(true, _typeId);
+
+            IPortableMetadata meta;
+
+            try
+            {
+                meta = _marsh.Metadata(_typeId);
+            }
+            catch (IgniteException)
+            {
+                meta = null;
+            }
+
+            if (meta == null)
+                sb = new StringBuilder("PortableObject [typeId=").Append(_typeId).Append(", idHash=" + idHash);
+            else
+            {
+                sb = new StringBuilder(meta.TypeName).Append(" [idHash=" + idHash);
+
+                if (!alreadyHandled)
+                {
+                    handled[_offset] = idHash;
+
+                    InitializeFields();
+                    
+                    foreach (string fieldName in meta.Fields)
+                    {
+                        sb.Append(", ");
+
+                        int fieldId = PortableUtils.FieldId(_typeId, fieldName, desc.NameConverter, desc.Mapper);
+
+                        int fieldPos;
+
+                        if (_fields.TryGetValue(fieldId, out fieldPos))
+                        {
+                            sb.Append(fieldName).Append('=');
+
+                            ToString0(sb, Field0<object>(fieldPos, null), handled);
+                        }
+                    }
+                }
+                else
+                    sb.Append(", ...");
+            }
+
+            sb.Append(']');
+
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Internal ToString routine with correct collections printout.
+        /// </summary>
+        /// <param name="sb">String builder.</param>
+        /// <param name="obj">Object to print.</param>
+        /// <param name="handled">Already handled objects.</param>
+        /// <returns>The same string builder.</returns>
+        private static void ToString0(StringBuilder sb, object obj, IDictionary<int, int> handled)
+        {
+            IEnumerable col = (obj is string) ? null : obj as IEnumerable;
+
+            if (col == null)
+            {
+                PortableUserObject obj0 = obj as PortableUserObject;
+
+                sb.Append(obj0 == null ? obj : obj0.ToString(handled));
+            }
+            else
+            {
+                sb.Append('[');
+
+                bool first = true;
+
+                foreach (object elem in col)
+                {
+                    if (first)
+                        first = false;
+                    else
+                        sb.Append(", ");
+
+                    ToString0(sb, elem, handled);
+                }
+
+                sb.Append(']');
+            }
+        }
+    }
+}