You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/29 17:20:34 UTC

[1/2] ignite git commit: IGNITE-1282: Started portables refactoring on writer side.

Repository: ignite
Updated Branches:
  refs/heads/ignite-1282 4c2965fee -> f6111b559


http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
index 3f42db8..e502840 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -20,12 +20,14 @@ namespace Apache.Ignite.Core.Impl.Portable
     using System;
     using System.Collections;
     using System.Collections.Generic;
-    using System.Diagnostics.CodeAnalysis;
     using System.IO;
+
     using Apache.Ignite.Core.Impl.Portable.IO;
     using Apache.Ignite.Core.Impl.Portable.Metadata;
     using Apache.Ignite.Core.Portable;
 
+    using PU = PortableUtils;
+
     /// <summary>
     /// Portable writer implementation.
     /// </summary>
@@ -79,7 +81,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Boolean value.</param>
         public void WriteBoolean(string fieldName, bool val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeBool, val, PortableSystemHandlers.WriteHndBoolTyped, 1);
+            WriteFieldId(fieldName, PU.TypeBool);
+
+            _stream.WriteInt(PU.LengthTypeId + 1);
+            _stream.WriteByte(PU.TypeBool);
+            _stream.WriteBool(val);
         }
         
         /// <summary>
@@ -98,8 +104,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Boolean array.</param>
         public void WriteBooleanArray(string fieldName, bool[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayBool, val,
-                PortableSystemHandlers.WriteHndBoolArrayTyped, val != null ? val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayBool);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + val.Length);
+                _stream.WriteByte(PU.TypeArrayBool);
+                PU.WriteBooleanArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -108,7 +122,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Boolean array.</param>
         public void WriteBooleanArray(bool[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndBoolArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayBool);
+                PU.WriteBooleanArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -118,7 +138,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Byte value.</param>
         public void WriteByte(string fieldName, byte val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeByte, val, PortableSystemHandlers.WriteHndByteTyped, 1);
+            WriteFieldId(fieldName, PU.TypeBool);
+
+            _stream.WriteInt(PU.LengthTypeId + 1);
+            _stream.WriteByte(PU.TypeByte);
+            _stream.WriteByte(val);
         }
 
         /// <summary>
@@ -137,8 +161,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Byte array.</param>
         public void WriteByteArray(string fieldName, byte[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayByte, val,
-                PortableSystemHandlers.WriteHndByteArrayTyped, val != null ? val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayByte);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + val.Length);
+                _stream.WriteByte(PU.TypeArrayByte);
+                PU.WriteByteArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -147,7 +179,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Byte array.</param>
         public void WriteByteArray(byte[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndByteArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayByte);
+                PU.WriteByteArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -157,7 +195,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Short value.</param>
         public void WriteShort(string fieldName, short val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeShort, val, PortableSystemHandlers.WriteHndShortTyped, 2);
+            WriteFieldId(fieldName, PU.TypeShort);
+
+            _stream.WriteInt(PU.LengthTypeId + 2);
+            _stream.WriteByte(PU.TypeShort);
+            _stream.WriteShort(val);
         }
 
         /// <summary>
@@ -176,8 +218,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Short array.</param>
         public void WriteShortArray(string fieldName, short[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayShort, val,
-                PortableSystemHandlers.WriteHndShortArrayTyped, val != null ? 2 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayShort);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 1));
+                _stream.WriteByte(PU.TypeArrayShort);
+                PU.WriteShortArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -186,7 +236,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Short array.</param>
         public void WriteShortArray(short[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndShortArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayShort);
+                PU.WriteShortArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -196,7 +252,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Char value.</param>
         public void WriteChar(string fieldName, char val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeChar, val, PortableSystemHandlers.WriteHndCharTyped, 2);
+            WriteFieldId(fieldName, PU.TypeChar);
+
+            _stream.WriteInt(PU.LengthTypeId + 2);
+            _stream.WriteByte(PU.TypeChar);
+            _stream.WriteChar(val);
         }
 
         /// <summary>
@@ -215,8 +275,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Char array.</param>
         public void WriteCharArray(string fieldName, char[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayChar, val,
-                PortableSystemHandlers.WriteHndCharArrayTyped, val != null ? 2 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayChar);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 1));
+                _stream.WriteByte(PU.TypeArrayChar);
+                PU.WriteCharArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -225,7 +293,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Char array.</param>
         public void WriteCharArray(char[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndCharArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayChar);
+                PU.WriteCharArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -235,7 +309,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Int value.</param>
         public void WriteInt(string fieldName, int val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeInt, val, PortableSystemHandlers.WriteHndIntTyped, 4);
+            WriteFieldId(fieldName, PU.TypeInt);
+
+            _stream.WriteInt(PU.LengthTypeId + 4);
+            _stream.WriteByte(PU.TypeInt);
+            _stream.WriteInt(val);
         }
 
         /// <summary>
@@ -254,8 +332,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Int array.</param>
         public void WriteIntArray(string fieldName, int[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayInt, val,
-                PortableSystemHandlers.WriteHndIntArrayTyped, val != null ? 4 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayInt);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 2));
+                _stream.WriteByte(PU.TypeArrayInt);
+                PU.WriteIntArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -264,7 +350,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Int array.</param>
         public void WriteIntArray(int[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndIntArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayInt);
+                PU.WriteIntArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -274,7 +366,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Long value.</param>
         public void WriteLong(string fieldName, long val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeLong, val, PortableSystemHandlers.WriteHndLongTyped, 8);
+            WriteFieldId(fieldName, PU.TypeLong);
+
+            _stream.WriteInt(PU.LengthTypeId + 8);
+            _stream.WriteByte(PU.TypeLong);
+            _stream.WriteLong(val);
         }
 
         /// <summary>
@@ -293,8 +389,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Long array.</param>
         public void WriteLongArray(string fieldName, long[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayLong, val,
-                PortableSystemHandlers.WriteHndLongArrayTyped, val != null ? 8 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayLong);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 3));
+                _stream.WriteByte(PU.TypeArrayLong);
+                PU.WriteLongArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -303,7 +407,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Long array.</param>
         public void WriteLongArray(long[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndLongArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayLong);
+                PU.WriteLongArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -313,7 +423,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Float value.</param>
         public void WriteFloat(string fieldName, float val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeFloat, val, PortableSystemHandlers.WriteHndFloatTyped, 4);
+            WriteFieldId(fieldName, PU.TypeFloat);
+
+            _stream.WriteInt(PU.LengthTypeId + 4);
+            _stream.WriteByte(PU.TypeFloat);
+            _stream.WriteFloat(val);
         }
 
         /// <summary>
@@ -332,8 +446,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Float array.</param>
         public void WriteFloatArray(string fieldName, float[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayFloat, val,
-                PortableSystemHandlers.WriteHndFloatArrayTyped, val != null ? 4 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayFloat);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 2));
+                _stream.WriteByte(PU.TypeArrayFloat);
+                PU.WriteFloatArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -342,7 +464,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Float array.</param>
         public void WriteFloatArray(float[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndFloatArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayFloat);
+                PU.WriteFloatArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -352,7 +480,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Double value.</param>
         public void WriteDouble(string fieldName, double val)
         {
-            WriteSimpleField(fieldName, PortableUtils.TypeDouble, val, PortableSystemHandlers.WriteHndDoubleTyped, 8);
+            WriteFieldId(fieldName, PU.TypeDouble);
+
+            _stream.WriteInt(PU.LengthTypeId + 8);
+            _stream.WriteByte(PU.TypeDouble);
+            _stream.WriteDouble(val);
         }
 
         /// <summary>
@@ -371,8 +503,16 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Double array.</param>
         public void WriteDoubleArray(string fieldName, double[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDouble, val,
-                PortableSystemHandlers.WriteHndDoubleArrayTyped, val != null ? 8 * val.Length + 4 : 0);
+            WriteFieldId(fieldName, PU.TypeArrayDouble);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + PU.LengthArraySize + (val.Length << 3));
+                _stream.WriteByte(PU.TypeArrayDouble);
+                PU.WriteDoubleArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -381,7 +521,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Double array.</param>
         public void WriteDoubleArray(double[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDoubleArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayDouble);
+                PU.WriteDoubleArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -391,7 +537,14 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Decimal value.</param>
         public void WriteDecimal(string fieldName, decimal val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeDecimal, val, PortableSystemHandlers.WriteHndDecimalTyped);
+            WriteFieldId(fieldName, PU.TypeDecimal);
+
+            int pos = SkipFieldLength();
+
+            _stream.WriteByte(PU.TypeDecimal);
+            PortableUtils.WriteDecimal(val, _stream);
+
+            WriteFieldLength(_stream, pos);
         }
 
         /// <summary>
@@ -400,7 +553,8 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Decimal value.</param>
         public void WriteDecimal(decimal val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDecimalTyped);
+            _stream.WriteByte(PU.TypeDecimal);
+            PortableUtils.WriteDecimal(val, _stream);
         }
 
         /// <summary>
@@ -410,8 +564,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Decimal array.</param>
         public void WriteDecimalArray(string fieldName, decimal[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDecimal, val,
-                PortableSystemHandlers.WriteHndDecimalArrayTyped);
+            WriteFieldId(fieldName, PU.TypeArrayDecimal);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeArrayDecimal);
+                PU.WriteDecimalArray(val, _stream);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
         
         /// <summary>
@@ -420,9 +585,72 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Decimal array.</param>
         public void WriteDecimalArray(decimal[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDecimalArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayDecimal);
+                PU.WriteDecimalArray(val, _stream);
+            }
         }
 
+//        /// <summary>
+//        /// Write named date value.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">Date value.</param>
+//        public void WriteDate(string fieldName, DateTime val)
+//        {
+//            WriteFieldId(fieldName, PU.TypeDate);
+//
+//            _stream.WriteInt(PU.LengthTypeId + 12);
+//
+//            _stream.WriteByte(PortableUtils.TypeDate);
+//            PortableUtils.WriteDate(val, _stream);
+//        }
+//
+//        /// <summary>
+//        /// Write date value.
+//        /// </summary>
+//        /// <param name="val">Date value.</param>
+//        public void WriteDate(DateTime val)
+//        {
+//            _stream.WriteByte(PortableUtils.TypeDate);
+//            PortableUtils.WriteDate(val, _stream);
+//        }
+//
+//        /// <summary>
+//        /// Write named date array.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">Date array.</param>
+//        public void WriteDateArray(string fieldName, DateTime[] val)
+//        {
+//            WriteFieldId(fieldName, PU.TypeDate);
+//
+//            if (val == null)
+//                WriteNullField();
+//            else
+//            {
+//                int pos = SkipFieldLength();
+//
+//                _stream.WriteByte(PortableUtils.TypeArrayDate);
+//                PortableUtils.WriteDateArray(val, _stream);
+//
+//                WriteFieldLength(_stream, pos);
+//            }
+//        }
+//
+//        /// <summary>
+//        /// Write date array.
+//        /// </summary>
+//        /// <param name="val">Date array.</param>
+//        public void WriteDateArray(DateTime[] val)
+//        {
+//            _stream.WriteByte(PortableUtils.TypeArrayDate);
+//            PortableUtils.WriteDateArray(val, _stream);
+//        }
+
         /// <summary>
         /// Write named date value.
         /// </summary>
@@ -430,8 +658,17 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Date value.</param>
         public void WriteDate(string fieldName, DateTime? val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeDate, val, PortableSystemHandlers.WriteHndDateTyped,
-                val.HasValue ? 12 : 0);
+            WriteFieldId(fieldName, PU.TypeDate);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + 12);
+
+                _stream.WriteByte(PortableUtils.TypeDate);
+                PortableUtils.WriteDate(val.Value, _stream);
+            }
         }
         
         /// <summary>
@@ -440,7 +677,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Date value.</param>
         public void WriteDate(DateTime? val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDateTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PortableUtils.TypeDate);
+                PortableUtils.WriteDate(val.Value, _stream);
+            }
         }
 
         /// <summary>
@@ -450,8 +693,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Date array.</param>
         public void WriteDateArray(string fieldName, DateTime?[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayDate, val,
-                PortableSystemHandlers.WriteHndDateArrayTyped);
+            WriteFieldId(fieldName, PU.TypeDate);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PortableUtils.TypeArrayDate);
+                PortableUtils.WriteDateArray(val, _stream);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -460,7 +714,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Date array.</param>
         public void WriteDateArray(DateTime?[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndDateArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PortableUtils.TypeArrayDate);
+                PortableUtils.WriteDateArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -470,7 +730,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">String value.</param>
         public void WriteString(string fieldName, string val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeString, val, PortableSystemHandlers.WriteHndStringTyped);
+            WriteFieldId(fieldName, PU.TypeString);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeString);
+                PU.WriteString(val, _stream);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -479,7 +751,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">String value.</param>
         public void WriteString(string val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndStringTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeString);
+                PU.WriteString(val, _stream);
+            }
         }
 
         /// <summary>
@@ -489,8 +767,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">String array.</param>
         public void WriteStringArray(string fieldName, string[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayString, val,
-                PortableSystemHandlers.WriteHndStringArrayTyped);
+            WriteFieldId(fieldName, PU.TypeArrayString);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeArrayString);
+                PU.WriteStringArray(val, _stream);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -499,9 +788,77 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">String array.</param>
         public void WriteStringArray(string[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndStringArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayString);
+                PU.WriteStringArray(val, _stream);
+            }
         }
 
+//        /// <summary>
+//        /// Write named GUID value.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">GUID value.</param>
+//        public void WriteGuid(string fieldName, Guid val)
+//        {
+//            WriteFieldId(fieldName, PU.TypeGuid);
+//
+//            _stream.WriteInt(PU.LengthTypeId + 16);
+//
+//            _stream.WriteByte(PU.TypeGuid);
+//            PU.WriteGuid(val, _stream);
+//        }
+//
+//        /// <summary>
+//        /// Write GUID value.
+//        /// </summary>
+//        /// <param name="val">GUID value.</param>
+//        public void WriteGuid(Guid val)
+//        {
+//            _stream.WriteByte(PU.TypeGuid);
+//            PU.WriteGuid(val, _stream);
+//        }
+//
+//        /// <summary>
+//        /// Write named GUID array.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">GUID array.</param>
+//        public void WriteGuidArray(string fieldName, Guid[] val)
+//        {
+//            WriteFieldId(fieldName, PU.TypeArrayGuid);
+//
+//            if (val == null)
+//                WriteNullField();
+//            else
+//            {
+//                int pos = SkipFieldLength();
+//
+//                _stream.WriteByte(PU.TypeArrayGuid);
+//                PU.WriteGuidArray(val, _stream);
+//
+//                WriteFieldLength(_stream, pos);
+//            }
+//        }
+//
+//        /// <summary>
+//        /// Write GUID array.
+//        /// </summary>
+//        /// <param name="val">GUID array.</param>
+//        public void WriteGuidArray(Guid[] val)
+//        {
+//            if (val == null)
+//                WriteNullRawField();
+//            else
+//            {
+//                _stream.WriteByte(PU.TypeArrayGuid);
+//                PU.WriteGuidArray(val, _stream);
+//            }
+//        }
+
         /// <summary>
         /// Write named GUID value.
         /// </summary>
@@ -509,8 +866,17 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">GUID value.</param>
         public void WriteGuid(string fieldName, Guid? val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeGuid, val, PortableSystemHandlers.WriteHndGuidTyped,
-                val.HasValue ? 16 : 0);
+            WriteFieldId(fieldName, PU.TypeGuid);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteInt(PU.LengthTypeId + 16);
+
+                _stream.WriteByte(PU.TypeGuid);
+                PU.WriteGuid(val.Value, _stream);
+            }
         }
 
         /// <summary>
@@ -519,7 +885,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">GUID value.</param>
         public void WriteGuid(Guid? val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndGuidTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeGuid);
+                PU.WriteGuid(val.Value, _stream);
+            }
         }
 
         /// <summary>
@@ -529,8 +901,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">GUID array.</param>
         public void WriteGuidArray(string fieldName, Guid?[] val)
         {
-            WriteSimpleNullableField(fieldName, PortableUtils.TypeArrayGuid, val,
-                PortableSystemHandlers.WriteHndGuidArrayTyped);
+            WriteFieldId(fieldName, PU.TypeArrayGuid);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeArrayGuid);
+                PU.WriteGuidArray(val, _stream);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -539,7 +922,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">GUID array.</param>
         public void WriteGuidArray(Guid?[] val)
         {
-            WriteSimpleNullableRawField(val, PortableSystemHandlers.WriteHndGuidArrayTyped);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayGuid);
+                PU.WriteGuidArray(val, _stream);
+            }
         }
 
         /// <summary>
@@ -550,7 +939,12 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Enum value.</param>
         public void WriteEnum<T>(string fieldName, T val)
         {
-            WriteField(fieldName, PortableUtils.TypeEnum, val, PortableSystemHandlers.WriteHndEnum);
+            WriteFieldId(fieldName, PU.TypeEnum);
+
+            _stream.WriteInt(PU.LengthTypeId + 16);
+
+            _stream.WriteByte(PU.TypeEnum);
+            PortableUtils.WriteEnum(_stream, (Enum)(object)val);
         }
 
         /// <summary>
@@ -560,7 +954,8 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Enum value.</param>
         public void WriteEnum<T>(T val)
         {
-            Write(val, PortableSystemHandlers.WriteHndEnum);
+            _stream.WriteByte(PU.TypeEnum);
+            PortableUtils.WriteEnum(_stream, (Enum)(object)val);
         }
 
         /// <summary>
@@ -571,7 +966,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Enum array.</param>
         public void WriteEnumArray<T>(string fieldName, T[] val)
         {
-            WriteField(fieldName, PortableUtils.TypeArrayEnum, val, PortableSystemHandlers.WriteHndEnumArray);
+            WriteFieldId(fieldName, PU.TypeArrayEnum);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeArrayEnum);
+                PortableUtils.WriteArray(val, this, true);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -581,7 +988,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Enum array.</param>
         public void WriteEnumArray<T>(T[] val)
         {
-            Write(val, PortableSystemHandlers.WriteHndEnumArray);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArrayEnum);
+                PortableUtils.WriteArray(val, this, true);
+            }
         }
 
         /// <summary>
@@ -592,7 +1005,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Object value.</param>
         public void WriteObject<T>(string fieldName, T val)
         {
-            WriteField(fieldName, PortableUtils.TypeObject, val, null);
+            WriteFieldId(fieldName, PU.TypeObject);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                Write(val);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -613,7 +1037,19 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Object array.</param>
         public void WriteObjectArray<T>(string fieldName, T[] val)
         {
-            WriteField(fieldName, PortableUtils.TypeArray, val, PortableSystemHandlers.WriteHndArray);
+            WriteFieldId(fieldName, PU.TypeArray);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                _stream.WriteByte(PU.TypeArray);
+                PortableUtils.WriteArray(val, this, true);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -623,7 +1059,13 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Object array.</param>
         public void WriteObjectArray<T>(T[] val)
         {
-            Write(val, PortableSystemHandlers.WriteHndArray);
+            if (val == null)
+                WriteNullRawField();
+            else
+            {
+                _stream.WriteByte(PU.TypeArray);
+                PortableUtils.WriteArray(val, this, true);
+            }
         }
 
         /// <summary>
@@ -633,7 +1075,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Collection.</param>
         public void WriteCollection(string fieldName, ICollection val)
         {
-            WriteField(fieldName, PortableUtils.TypeCollection, val, null);
+            WriteFieldId(fieldName, PU.TypeCollection);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                Write(val);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -653,7 +1106,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Collection.</param>
         public void WriteGenericCollection<T>(string fieldName, ICollection<T> val)
         {
-            WriteField(fieldName, PortableUtils.TypeCollection, val, null);
+            WriteFieldId(fieldName, PU.TypeCollection);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                Write(val);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -673,7 +1137,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Dictionary.</param>
         public void WriteDictionary(string fieldName, IDictionary val)
         {
-            WriteField(fieldName, PortableUtils.TypeDictionary, val, null);
+            WriteFieldId(fieldName, PU.TypeDictionary);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                Write(val);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -692,7 +1167,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="val">Dictionary.</param>
         public void WriteGenericDictionary<TK, TV>(string fieldName, IDictionary<TK, TV> val)
         {
-            WriteField(fieldName, PortableUtils.TypeDictionary, val, null);
+            WriteFieldId(fieldName, PU.TypeDictionary);
+
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                int pos = SkipFieldLength();
+
+                Write(val);
+
+                WriteFieldLength(_stream, pos);
+            }
         }
 
         /// <summary>
@@ -705,6 +1191,23 @@ namespace Apache.Ignite.Core.Impl.Portable
         }
 
         /// <summary>
+        /// Write NULL field.
+        /// </summary>
+        public void WriteNullField()
+        {
+            _stream.WriteInt(1);
+            _stream.WriteByte(PU.HdrNull);
+        }
+
+        /// <summary>
+        /// Write NULL raw field.
+        /// </summary>
+        public void WriteNullRawField()
+        {
+            _stream.WriteByte(PU.HdrNull);
+        }
+
+        /// <summary>
         /// Get raw writer.
         /// </summary>
         /// <returns>
@@ -742,319 +1245,271 @@ namespace Apache.Ignite.Core.Impl.Portable
             _marsh = marsh;
             _stream = stream;
         }
-
-        /// <summary>
-        /// Write object.
-        /// </summary>
-        /// <param name="obj">Object.</param>
-        internal void Write<T>(T obj)
-        {
-            Write(obj, null);
-        }
-
+        
         /// <summary>
         /// Write object.
         /// </summary>
         /// <param name="obj">Object.</param>
-        /// <param name="handler">Optional write handler.</param>
-        [SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
-        internal void Write<T>(T obj, object handler)
+        public void Write<T>(T obj)
         {
-            // Write null.
+            // Handle special case for null.
             if (obj == null)
             {
-                _stream.WriteByte(PortableUtils.HdrNull);
+                _stream.WriteByte(PU.HdrNull);
 
                 return;
             }
 
-            if (_builder != null)
-            {
-                // Special case for portable object during build.
-                PortableUserObject portObj = obj as PortableUserObject;
-
-                if (portObj != null)
-                {
-                    if (!WriteHandle(_stream.Position, portObj))
-                        _builder.ProcessPortable(_stream, portObj);
-
-                    return;
-                }
-
-                // Special case for builder during build.
-                PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
+            // We use GetType() of a real object instead of typeof(T) to take advantage of 
+            // automatic Nullable'1 unwrapping.
+            Type type = obj.GetType();
 
-                if (portBuilder != null)
-                {
-                    if (!WriteHandle(_stream.Position, portBuilder))
-                        _builder.ProcessBuilder(_stream, portBuilder);
+            // Handle common case when primitive is written.
+            if (type.IsPrimitive)
+            {
+                WritePrimitive(obj, type);
 
-                    return;
-                }
+                return;
             }
 
-            // Try writting as well-known type.
-            if (InvokeHandler(handler, handler as PortableSystemWriteDelegate, obj))
+            // Handle special case for builder.
+            if (WriteBuilderSpecials(obj))
                 return;
 
-            Type type = obj.GetType();
-
+            // Suppose that we faced normal object and perform descriptor lookup.
             IPortableTypeDescriptor desc = _marsh.Descriptor(type);
 
-            object typedHandler;
-            PortableSystemWriteDelegate untypedHandler;
-
-            if (desc == null)
-            {
-                typedHandler = null;
-                untypedHandler = PortableSystemHandlers.WriteHandler(type);
-            }
-            else
-            {
-                typedHandler = desc.TypedHandler;
-                untypedHandler = desc.UntypedHandler;
-            }
-
-            if (InvokeHandler(typedHandler, untypedHandler, obj))
-                return;
-
-            if (desc == null)
+            if (desc != null)
             {
-                if (!type.IsSerializable)
-                    // If neither handler, nor descriptor exist, and not serializable, this is an exception.
-                    throw new PortableException("Unsupported object type [type=" + type +
-                        ", object=" + obj + ']');
-
-                Write(new SerializableObjectHolder(obj));
+                // Writing normal object.
+                var pos = _stream.Position;
 
-                return;
-            }
-
-            int pos = _stream.Position;
-
-            // Dealing with handles.
-            if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
-                return;
+                // Dealing with handles.
+                if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
+                    return;
 
-            // Write header.
-            _stream.WriteByte(PortableUtils.HdrFull);
+                // Write header.
+                _stream.WriteByte(PU.HdrFull);
+                _stream.WriteBool(desc.UserType);
+                _stream.WriteInt(desc.TypeId);
+                _stream.WriteInt(obj.GetHashCode());
 
-            _stream.WriteBool(desc.UserType);
-            _stream.WriteInt(desc.TypeId);
-            _stream.WriteInt(obj.GetHashCode());
+                // Skip length as it is not known in the first place.
+                _stream.Seek(8, SeekOrigin.Current);
 
-            // Skip length as it is not known in the first place.
-            _stream.Seek(8, SeekOrigin.Current);
+                // Preserve old frame.
+                int oldTypeId = _curTypeId;
+                IPortableNameMapper oldConverter = _curConverter;
+                IPortableIdMapper oldMapper = _curMapper;
+                IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
+                long oldRawPos = _curRawPos;
 
-            // Preserve old frame.
-            int oldTypeId = _curTypeId;
-            IPortableNameMapper oldConverter = _curConverter;
-            IPortableIdMapper oldMapper = _curMapper;
-            IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
-            long oldRawPos = _curRawPos;
+                // Push new frame.
+                _curTypeId = desc.TypeId;
+                _curConverter = desc.NameConverter;
+                _curMapper = desc.Mapper;
+                _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
+                _curRawPos = 0;
 
-            // Push new frame.
-            _curTypeId = desc.TypeId;
-            _curConverter = desc.NameConverter;
-            _curMapper = desc.Mapper;
-            _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
-            _curRawPos = 0;
+                // Write object fields.
+                desc.Serializer.WritePortable(obj, this);
 
-            // Write object fields.
-            desc.Serializer.WritePortable(obj, this);
+                // Calculate and write length.
+                int len = _stream.Position - pos;
 
-            // Calculate and write length.
-            int retPos = _stream.Position;
+                _stream.WriteInt(pos + 10, len);
 
-            _stream.Seek(pos + 10, SeekOrigin.Begin);
+                if (_curRawPos != 0)
+                    _stream.WriteInt(pos + 14, (int)(_curRawPos - pos));
+                else
+                    _stream.WriteInt(pos + 14, len);
 
-            int len = retPos - pos;
+                // 13. Collect metadata.
+                if (_curMetaHnd != null)
+                {
+                    IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
 
-            _stream.WriteInt(len);
+                    if (meta != null)
+                        SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+                }
 
-            if (_curRawPos != 0)
-                // When set, it is difference between object head and raw position.
-                _stream.WriteInt((int)(_curRawPos - pos));
+                // Restore old frame.
+                _curTypeId = oldTypeId;
+                _curConverter = oldConverter;
+                _curMapper = oldMapper;
+                _curMetaHnd = oldMetaHnd;
+                _curRawPos = oldRawPos;
+            }
             else
-                // When no set, it is equal to object length.
-                _stream.WriteInt(len);
-
-            _stream.Seek(retPos, SeekOrigin.Begin);
-
-            // 13. Collect metadata.
-            if (_curMetaHnd != null)
             {
-                IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
+                // Are we dealing with a well-known type?
+                PortableSystemWriteDelegate handler = PortableSystemHandlers.GetWriteHandler(type);
 
-                if (meta != null)
-                    SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+                if (handler != null)
+                    handler.Invoke(this, obj);
+                else
+                {
+                    // Last chance: is object seializable?
+                    if (type.IsSerializable)
+                        Write(new SerializableObjectHolder(obj));
+                    else
+                        // We did our best, object cannot be marshalled.
+                        throw new PortableException("Unsupported object type [type=" + type + ", object=" + obj + ']');
+                }
             }
-
-            // Restore old frame.
-            _curTypeId = oldTypeId;
-            _curConverter = oldConverter;
-            _curMapper = oldMapper;
-            _curMetaHnd = oldMetaHnd;
-            _curRawPos = oldRawPos;
         }
 
         /// <summary>
-        /// Add handle to handles map.
+        /// Write primitive type.
         /// </summary>
-        /// <param name="pos">Position in stream.</param>
-        /// <param name="obj">Object.</param>
-        /// <returns><c>true</c> if object was written as handle.</returns>
-        private bool WriteHandle(long pos, object obj)
+        /// <param name="val">Object.</param>
+        /// <param name="type">Type.</param>
+        public unsafe void WritePrimitive<T>(T val, Type type)
         {
-            if (_hnds == null)
-            {
-                // Cache absolute handle position.
-                _hnds = new PortableHandleDictionary<object, long>(obj, pos);
+            // .Net defines 14 primitive types. We support 12 - excluding IntPtr and UIntPtr.
+            // Types check sequence is designed to minimize comparisons for the most frequent types.
 
-                return false;
+            if (type == typeof(int))
+            {
+                _stream.WriteByte(PU.TypeInt);
+                _stream.WriteInt((int)(object)val);
             }
-
-            long hndPos;
-
-            if (!_hnds.TryGetValue(obj, out hndPos))
+            else if (type == typeof(long))
             {
-                // Cache absolute handle position.
-                _hnds.Add(obj, pos);
-
-                return false;
+                _stream.WriteByte(PU.TypeLong);
+                _stream.WriteLong((long)(object)val);
             }
-
-            _stream.WriteByte(PortableUtils.HdrHnd);
-
-            // Handle is written as difference between position before header and handle position.
-            _stream.WriteInt((int)(pos - hndPos));
-
-            return true;
-        }
-
-        /// <summary>
-        /// Try invoking predefined handler on object.
-        /// </summary>
-        /// <param name="typedHandler">Handler</param>
-        /// <param name="untypedHandler">Not typed handler.</param>
-        /// <param name="obj">Object.</param>
-        /// <returns>True if handler was called.</returns>
-        private bool InvokeHandler<T>(object typedHandler, PortableSystemWriteDelegate untypedHandler, T obj)
-        {
-            var typedHandler0 = typedHandler as PortableSystemTypedWriteDelegate<T>;
-
-            if (typedHandler0 != null)
+            else if (type == typeof(bool))
+            {
+                _stream.WriteByte(PU.TypeBool);
+                _stream.WriteBool((bool)(object)val);
+            }
+            else if (type == typeof(byte))
+            {
+                _stream.WriteByte(PU.TypeByte);
+                _stream.WriteByte((byte)(object)val);
+            }
+            else if (type == typeof(short))
+            {
+                _stream.WriteByte(PU.TypeShort);
+                _stream.WriteShort((short)(object)val);
+            }
+            else if (type == typeof (char))
+            {
+                _stream.WriteByte(PU.TypeChar);
+                _stream.WriteChar((char)(object)val);
+            }
+            else if (type == typeof(float))
             {
-                typedHandler0.Invoke(_stream, obj);
+                _stream.WriteByte(PU.TypeFloat);
+                _stream.WriteFloat((float)(object)val);
+            }
+            else if (type == typeof(double))
+            {
+                _stream.WriteByte(PU.TypeDouble);
+                _stream.WriteDouble((double)(object)val);
+            }
+            else if (type == typeof(sbyte))
+            {
+                sbyte val0 = (sbyte)(object)val;
 
-                return true;
+                _stream.WriteByte(PU.TypeByte);
+                _stream.WriteByte(*(byte*)&val0);
             }
+            else if (type == typeof(ushort))
+            {
+                ushort val0 = (ushort)(object)val;
 
-            if (untypedHandler != null)
+                _stream.WriteByte(PU.TypeShort);
+                _stream.WriteShort(*(short*)&val0);
+            }
+            else if (type == typeof(uint))
             {
-                untypedHandler.Invoke(this, obj);
+                uint val0 = (uint)(object)val;
 
-                return true;
+                _stream.WriteByte(PU.TypeInt);
+                _stream.WriteInt(*(int*)&val0);
             }
+            else if (type == typeof(ulong))
+            {
+                ulong val0 = (ulong)(object)val;
 
-            return false;
+                _stream.WriteByte(PU.TypeLong);
+                _stream.WriteLong(*(long*)&val0);
+            }
+            else
+                throw new PortableException("Unsupported object type [type=" + type.FullName + ", object=" + val + ']');
         }
 
         /// <summary>
-        /// Write simple field with known length.
+        /// Try writing object as special builder type.
         /// </summary>
-        /// <param name="fieldId">Field ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        /// <param name="len">Length.</param>
-        private void WriteSimpleField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler, int len)
+        /// <param name="obj">Object.</param>
+        /// <returns>True if object was written, false otherwise.</returns>
+        private bool WriteBuilderSpecials<T>(T obj)
         {
-            CheckNotRaw();
-
-            _stream.WriteInt(fieldId);
-            _stream.WriteInt(1 + len); // Additional byte for field type.
+            if (_builder != null)
+            {
+                // Special case for portable object during build.
+                PortableUserObject portObj = obj as PortableUserObject;
 
-            handler(_stream, val);
-        }
+                if (portObj != null)
+                {
+                    if (!WriteHandle(_stream.Position, portObj))
+                        _builder.ProcessPortable(_stream, portObj);
 
-        /// <summary>
-        /// Write simple nullable field with unknown length.
-        /// </summary>
-        /// <param name="fieldId">Field ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        private void WriteSimpleNullableField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler)
-        {
-            CheckNotRaw();
+                    return true;
+                }
 
-            _stream.WriteInt(fieldId);
+                // Special case for builder during build.
+                PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
 
-            if (val == null)
-            {
-                _stream.WriteInt(1);
+                if (portBuilder != null)
+                {
+                    if (!WriteHandle(_stream.Position, portBuilder))
+                        _builder.ProcessBuilder(_stream, portBuilder);
 
-                _stream.WriteByte(PortableUtils.HdrNull);
+                    return true;
+                }
             }
-            else
-            {
-                int pos = _stream.Position;
-
-                _stream.Seek(4, SeekOrigin.Current);
 
-                handler(_stream, val);
-
-                WriteFieldLength(_stream, pos);
-            }
+            return false;
         }
 
         /// <summary>
-        /// Write simple nullable field with known length.
+        /// Add handle to handles map.
         /// </summary>
-        /// <param name="fieldId">Field ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        /// <param name="len">Length.</param>
-        private void WriteSimpleNullableField<T>(int fieldId, T val, PortableSystemTypedWriteDelegate<T> handler, int len)
+        /// <param name="pos">Position in stream.</param>
+        /// <param name="obj">Object.</param>
+        /// <returns><c>true</c> if object was written as handle.</returns>
+        private bool WriteHandle(long pos, object obj)
         {
-            CheckNotRaw();
-
-            _stream.WriteInt(fieldId);
-
-            if (val == null)
-            {
-                _stream.WriteInt(1);
-
-                _stream.WriteByte(PortableUtils.HdrNull);
-            }
-            else
+            if (_hnds == null)
             {
-                _stream.WriteInt(1 + len);
+                // Cache absolute handle position.
+                _hnds = new PortableHandleDictionary<object, long>(obj, pos);
 
-                handler(_stream, val);
+                return false;
             }
-        }
 
-        /// <summary>
-        /// Write field.
-        /// </summary>
-        /// <param name="fieldId">Field ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        private void WriteField(int fieldId, object val, PortableSystemWriteDelegate handler)
-        {
-            CheckNotRaw();
+            long hndPos;
 
-            _stream.WriteInt(fieldId);
+            if (!_hnds.TryGetValue(obj, out hndPos))
+            {
+                // Cache absolute handle position.
+                _hnds.Add(obj, pos);
 
-            int pos = _stream.Position;
+                return false;
+            }
 
-            _stream.Seek(4, SeekOrigin.Current);
+            _stream.WriteByte(PU.HdrHnd);
 
-            Write(val, handler);
+            // Handle is written as difference between position before header and handle position.
+            _stream.WriteInt((int)(pos - hndPos));
 
-            WriteFieldLength(_stream, pos);
+            return true;
         }
-        
+
         /// <summary>
         /// Perform action with detached semantics.
         /// </summary>
@@ -1123,97 +1578,41 @@ namespace Apache.Ignite.Core.Impl.Portable
                 // Collections, Enums and non-primitive arrays do not have descriptors
                 // and this is fine here because we cannot know whether their members
                 // are portable.
-                return _marsh.Descriptor(type) != null;
+                return _marsh.Descriptor(type) != null || PortableSystemHandlers.GetWriteHandler(type) != null;
             }
 
             return true;
         }
-
-        /// <summary>
-        /// Write simple field with known length.
-        /// </summary>
-        /// <param name="fieldName">Field name.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        /// <param name="len">Length.</param>
-        private void WriteSimpleField<T>(string fieldName, byte typeId, T val,
-            PortableSystemTypedWriteDelegate<T> handler, int len)
-        {
-            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
-
-            WriteSimpleField(fieldId, val, handler, len);
-
-            if (_curMetaHnd != null)
-                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
-        }
-
+        
         /// <summary>
-        /// Write simple nullable field with unknown length.
+        /// Write field ID.
         /// </summary>
         /// <param name="fieldName">Field name.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        private void WriteSimpleNullableField<T>(string fieldName, byte typeId, T val,
-            PortableSystemTypedWriteDelegate<T> handler)
+        /// <param name="fieldTypeId">Field type ID.</param>
+        private void WriteFieldId(string fieldName, byte fieldTypeId)
         {
-            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
-
-            WriteSimpleNullableField(fieldId, val, handler);
-
-            if (_curMetaHnd != null)
-                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
-        }
+            if (_curRawPos != 0)
+                throw new PortableException("Cannot write named fields after raw data is written.");
 
-        /// <summary>
-        /// Write simple nullable field with known length.
-        /// </summary>
-        /// <param name="fieldName">Field name.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        /// <param name="len">Length.</param>
-        private void WriteSimpleNullableField<T>(string fieldName, byte typeId, T val,
-            PortableSystemTypedWriteDelegate<T> handler, int len)
-        {
-            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+            int fieldId = PU.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
 
-            WriteSimpleNullableField(fieldId, val, handler, len);
+            _stream.WriteInt(fieldId);
 
             if (_curMetaHnd != null)
-                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+                _curMetaHnd.OnFieldWrite(fieldId, fieldName, fieldTypeId);
         }
 
         /// <summary>
-        /// Write nullable raw field.
+        /// Skip field lenght and return position where it is to be written.
         /// </summary>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        private void WriteSimpleNullableRawField<T>(T val, PortableSystemTypedWriteDelegate<T> handler)
-        {
-            if (val == null)
-                _stream.WriteByte(PortableUtils.HdrNull);
-            else
-                handler(_stream, val);
-        }
-
-        /// <summary>
-        /// Write field.
-        /// </summary>
-        /// <param name="fieldName">Field name.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="val">Value.</param>
-        /// <param name="handler">Handler.</param>
-        private void WriteField(string fieldName, byte typeId, object val,
-            PortableSystemWriteDelegate handler)
+        /// <returns></returns>
+        private int SkipFieldLength()
         {
-            int fieldId = PortableUtils.FieldId(_curTypeId, fieldName, _curConverter, _curMapper);
+            int pos = _stream.Position;
 
-            WriteField(fieldId, val, handler);
+            _stream.Seek(4, SeekOrigin.Current);
 
-            if (_curMetaHnd != null)
-                _curMetaHnd.OnFieldWrite(fieldId, fieldName, typeId);
+            return pos;
         }
 
         /// <summary>
@@ -1223,24 +1622,11 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="pos">Position where length should reside</param>
         private static void WriteFieldLength(IPortableStream stream, int pos)
         {
-            int retPos = stream.Position;
-
-            stream.Seek(pos, SeekOrigin.Begin);
-
-            stream.WriteInt(retPos - pos - 4);
-
-            stream.Seek(retPos, SeekOrigin.Begin);
+            // Length is is a difference between current position and previously recorder 
+            // length placeholder position minus 4 bytes for the length itself.
+            stream.WriteInt(pos, stream.Position - pos - 4);
         }
-
-        /// <summary>
-        /// Ensure that we are not in raw mode.
-        /// </summary>
-        private void CheckNotRaw()
-        {
-            if (_curRawPos != 0)
-                throw new PortableException("Cannot write named fields after raw data is written.");
-        }
-
+        
         /// <summary>
         /// Saves metadata for this session.
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableRawWriter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableRawWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableRawWriter.cs
index eacfde3..42d8c66 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableRawWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableRawWriter.cs
@@ -134,6 +134,18 @@ namespace Apache.Ignite.Core.Portable
         /// <param name="val">Decimal array.</param>
         void WriteDecimalArray(decimal[] val);
 
+//        /// <summary>
+//        /// Write date value.
+//        /// </summary>
+//        /// <param name="val">Date value.</param>
+//        void WriteDate(DateTime val);
+//
+//        /// <summary>
+//        /// Write date array.
+//        /// </summary>
+//        /// <param name="val">Date array.</param>
+//        void WriteDateArray(DateTime[] val);
+
         /// <summary>
         /// Write date value.
         /// </summary>
@@ -158,6 +170,18 @@ namespace Apache.Ignite.Core.Portable
         /// <param name="val">String array.</param>
         void WriteStringArray(string[] val);
 
+//        /// <summary>
+//        /// Write GUID value.
+//        /// </summary>
+//        /// <param name="val">GUID value.</param>
+//        void WriteGuid(Guid val);
+//
+//        /// <summary>
+//        /// Write GUID array.
+//        /// </summary>
+//        /// <param name="val">GUID array.</param>
+//        void WriteGuidArray(Guid[] val);
+
         /// <summary>
         /// Write GUID value.
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableWriter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableWriter.cs
index 8df2d50..5bb2625 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Portable/IPortableWriter.cs
@@ -152,6 +152,20 @@ namespace Apache.Ignite.Core.Portable
         /// <param name="val">Decimal array.</param>
         void WriteDecimalArray(string fieldName, decimal[] val);
 
+//        /// <summary>
+//        /// Write named date value.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">Date value.</param>
+//        void WriteDate(string fieldName, DateTime val);
+//
+//        /// <summary>
+//        /// Write named date array.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">Date array.</param>
+//        void WriteDateArray(string fieldName, DateTime[] val);
+
         /// <summary>
         /// Write named date value.
         /// </summary>
@@ -180,6 +194,20 @@ namespace Apache.Ignite.Core.Portable
         /// <param name="val">String array.</param>
         void WriteStringArray(string fieldName, string[] val);
 
+//        /// <summary>
+//        /// Write named GUID value.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">GUID value.</param>
+//        void WriteGuid(string fieldName, Guid val);
+//
+//        /// <summary>
+//        /// Write named GUID array.
+//        /// </summary>
+//        /// <param name="fieldName">Field name.</param>
+//        /// <param name="val">GUID array.</param>
+//        void WriteGuidArray(string fieldName, Guid[] val);
+
         /// <summary>
         /// Write named GUID value.
         /// </summary>


[2/2] ignite git commit: IGNITE-1282: Started portables refactoring on writer side.

Posted by vo...@apache.org.
IGNITE-1282: Started portables refactoring on writer side.


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

Branch: refs/heads/ignite-1282
Commit: f6111b55927f6df9a0900bf5c906eecb23f3d422
Parents: 4c2965f
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Sep 29 18:21:15 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Sep 29 18:21:15 2015 +0300

----------------------------------------------------------------------
 .../Impl/Portable/IPortableTypeDescriptor.cs    |   16 -
 .../Impl/Portable/PortableBuilderImpl.cs        |   10 +-
 .../Impl/Portable/PortableFullTypeDescriptor.cs |   30 +-
 .../Impl/Portable/PortableMarshaller.cs         |   72 +-
 .../Portable/PortableSurrogateTypeDescriptor.cs |   12 -
 .../Impl/Portable/PortableSystemHandlers.cs     |  952 +++++---------
 .../Impl/Portable/PortableUtils.cs              |   87 +-
 .../Impl/Portable/PortableWriterImpl.cs         | 1162 ++++++++++++------
 .../Portable/IPortableRawWriter.cs              |   24 +
 .../Portable/IPortableWriter.cs                 |   28 +
 10 files changed, 1205 insertions(+), 1188 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
index 4a4f0dc..62597d5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/IPortableTypeDescriptor.cs
@@ -104,21 +104,5 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             get;
         }
-
-        /// <summary>
-        /// Typed handler.
-        /// </summary>
-        object TypedHandler
-        {
-            get;
-        }
-
-        /// <summary>
-        /// Untyped handler.
-        /// </summary>
-        PortableSystemWriteDelegate UntypedHandler
-        {
-            get;
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/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 dc0f570..7ea565b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
@@ -197,7 +197,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             try
             {
                 // Write.
-                writer.Write(this, null);
+                writer.Write(this);
                 
                 // Process metadata.
                 _portables.Marshaller.FinishMarshal(writer);
@@ -409,7 +409,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                     object cachedVal;
 
                     if (_parent._cache != null && _parent._cache.TryGetValue(inStartPos, out cachedVal)) {
-                        ctx.Writer.Write(cachedVal, null);
+                        ctx.Writer.Write(cachedVal);
                     }
                     else
                     {
@@ -445,7 +445,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                                 {
                                     // Replace field with new value.
                                     if (fieldVal != PortableBuilderField.RmvMarkerObj)
-                                        ctx.Writer.Write(fieldVal, null);
+                                        ctx.Writer.Write(fieldVal);
 
                                     vals.Remove(inFieldId);
                                 }
@@ -453,7 +453,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                                 {
                                     // If field was requested earlier, then we must write tracked value
                                     if (_parent._cache != null && _parent._cache.TryGetValue(inFieldDataPos, out fieldVal))
-                                        ctx.Writer.Write(fieldVal, null);
+                                        ctx.Writer.Write(fieldVal);
                                     else
                                         // Filed is not tracked, re-write as is.
                                         Mutate0(ctx, inStream, outStream, false, 0, EmptyVals);                                    
@@ -481,7 +481,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
                                 outStream.Seek(4, SeekOrigin.Current);
 
-                                ctx.Writer.Write(valEntry.Value, null);
+                                ctx.Writer.Write(valEntry.Value);
 
                                 int fieldEndPos = outStream.Position;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
index f294cbd..79b860f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableFullTypeDescriptor.cs
@@ -55,12 +55,6 @@ namespace Apache.Ignite.Core.Impl.Portable
         /** Affinity field key name. */
         private readonly string _affKeyFieldName;
 
-        /** Typed handler. */
-        private readonly object _typedHandler;
-
-        /** Untyped handler. */
-        private readonly PortableSystemWriteDelegate _untypedHandler;
-
         /// <summary>
         /// Constructor.
         /// </summary>
@@ -74,8 +68,6 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="metaEnabled">Metadata enabled flag.</param>
         /// <param name="keepDeserialized">Whether to cache deserialized value in IPortableObject</param>
         /// <param name="affKeyFieldName">Affinity field key name.</param>
-        /// <param name="typedHandler">Typed handler.</param>
-        /// <param name="untypedHandler">Untyped handler.</param>
         public PortableFullTypeDescriptor(
             Type type, 
             int typeId, 
@@ -86,9 +78,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             IPortableSerializer serializer, 
             bool metaEnabled, 
             bool keepDeserialized, 
-            string affKeyFieldName, 
-            object typedHandler,
-            PortableSystemWriteDelegate untypedHandler)
+            string affKeyFieldName)
         {
             _type = type;
             _typeId = typeId;
@@ -100,8 +90,6 @@ namespace Apache.Ignite.Core.Impl.Portable
             _metaEnabled = metaEnabled;
             _keepDeserialized = keepDeserialized;
             _affKeyFieldName = affKeyFieldName;
-            _typedHandler = typedHandler;
-            _untypedHandler = untypedHandler;
         }
 
         /// <summary>
@@ -183,21 +171,5 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             get { return _affKeyFieldName; }
         }
-
-        /// <summary>
-        /// Typed handler.
-        /// </summary>
-        public object TypedHandler
-        {
-            get { return _typedHandler; }
-        }
-
-        /// <summary>
-        /// Untyped handler.
-        /// </summary>
-        public PortableSystemWriteDelegate UntypedHandler
-        {
-            get { return _untypedHandler; }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
index 6286ebb..f41962d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableMarshaller.cs
@@ -77,49 +77,6 @@ namespace Apache.Ignite.Core.Impl.Portable
                     throw new PortableException("Assembly name cannot be empty string: " + typeCfg);
             }
 
-            // Define predefined types.
-            AddPredefinedType(typeof(bool), PortableUtils.TypeBool, PortableSystemHandlers.WriteHndBoolTyped, PortableSystemHandlers.WriteHndBool);
-            AddPredefinedType(typeof(byte), PortableUtils.TypeByte, PortableSystemHandlers.WriteHndByteTyped, PortableSystemHandlers.WriteHndByte);
-            AddPredefinedType(typeof(short), PortableUtils.TypeShort, PortableSystemHandlers.WriteHndShortTyped, PortableSystemHandlers.WriteHndShort);
-            AddPredefinedType(typeof(char), PortableUtils.TypeChar, PortableSystemHandlers.WriteHndCharTyped, PortableSystemHandlers.WriteHndChar);
-            AddPredefinedType(typeof(int), PortableUtils.TypeInt, PortableSystemHandlers.WriteHndIntTyped, PortableSystemHandlers.WriteHndInt);
-            AddPredefinedType(typeof(long), PortableUtils.TypeLong, PortableSystemHandlers.WriteHndLongTyped, PortableSystemHandlers.WriteHndLong);
-            AddPredefinedType(typeof(float), PortableUtils.TypeFloat, PortableSystemHandlers.WriteHndFloatTyped, PortableSystemHandlers.WriteHndFloat);
-            AddPredefinedType(typeof(double), PortableUtils.TypeDouble, PortableSystemHandlers.WriteHndDoubleTyped, PortableSystemHandlers.WriteHndDouble);
-            AddPredefinedType(typeof(string), PortableUtils.TypeString, PortableSystemHandlers.WriteHndStringTyped, PortableSystemHandlers.WriteHndString);
-            AddPredefinedType(typeof(decimal), PortableUtils.TypeDecimal, PortableSystemHandlers.WriteHndDecimalTyped, PortableSystemHandlers.WriteHndDecimal);
-            AddPredefinedType(typeof(DateTime), PortableUtils.TypeDate, PortableSystemHandlers.WriteHndDateTyped, PortableSystemHandlers.WriteHndDate);
-            AddPredefinedType(typeof(Guid), PortableUtils.TypeGuid, PortableSystemHandlers.WriteHndGuidTyped, PortableSystemHandlers.WriteHndGuid);
-
-            // TODO: Remove this registration
-            AddPredefinedType(typeof(PortableUserObject), PortableUtils.TypePortable, PortableSystemHandlers.WriteHndPortableTyped, 
-                PortableSystemHandlers.WriteHndPortable);
-
-            AddPredefinedType(typeof(bool[]), PortableUtils.TypeArrayBool, PortableSystemHandlers.WriteHndBoolArrayTyped,
-                PortableSystemHandlers.WriteHndBoolArray);
-            AddPredefinedType(typeof(byte[]), PortableUtils.TypeArrayByte, PortableSystemHandlers.WriteHndByteArrayTyped,
-                PortableSystemHandlers.WriteHndByteArray);
-            AddPredefinedType(typeof(short[]), PortableUtils.TypeArrayShort, PortableSystemHandlers.WriteHndShortArrayTyped,
-                PortableSystemHandlers.WriteHndShortArray);
-            AddPredefinedType(typeof(char[]), PortableUtils.TypeArrayChar, PortableSystemHandlers.WriteHndCharArrayTyped,
-                PortableSystemHandlers.WriteHndCharArray);
-            AddPredefinedType(typeof(int[]), PortableUtils.TypeArrayInt, PortableSystemHandlers.WriteHndIntArrayTyped,
-                PortableSystemHandlers.WriteHndIntArray);
-            AddPredefinedType(typeof(long[]), PortableUtils.TypeArrayLong, PortableSystemHandlers.WriteHndLongArrayTyped,
-                PortableSystemHandlers.WriteHndLongArray);
-            AddPredefinedType(typeof(float[]), PortableUtils.TypeArrayFloat, PortableSystemHandlers.WriteHndFloatArrayTyped,
-                PortableSystemHandlers.WriteHndFloatArray);
-            AddPredefinedType(typeof(double[]), PortableUtils.TypeArrayDouble, PortableSystemHandlers.WriteHndDoubleArrayTyped,
-                PortableSystemHandlers.WriteHndDoubleArray);
-            AddPredefinedType(typeof(decimal[]), PortableUtils.TypeArrayDecimal, PortableSystemHandlers.WriteHndDecimalArrayTyped,
-                PortableSystemHandlers.WriteHndDecimalArray);
-            AddPredefinedType(typeof(string[]), PortableUtils.TypeArrayString, PortableSystemHandlers.WriteHndStringArrayTyped,
-                PortableSystemHandlers.WriteHndStringArray);
-            AddPredefinedType(typeof(DateTime?[]), PortableUtils.TypeArrayDate, PortableSystemHandlers.WriteHndDateArrayTyped,
-                PortableSystemHandlers.WriteHndDateArray);
-            AddPredefinedType(typeof(Guid?[]), PortableUtils.TypeArrayGuid, PortableSystemHandlers.WriteHndGuidArrayTyped,
-                PortableSystemHandlers.WriteHndGuidArray);
-
             // Define system types. They use internal reflective stuff, so configuration doesn't affect them.
             AddSystemTypes();
 
@@ -457,7 +414,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                     refSerializer.Register(type, typeId, nameMapper, idMapper);
 
                 AddType(type, typeId, typeName, true, metaEnabled, keepDeserialized, nameMapper, idMapper, serializer,
-                    typeCfg.AffinityKeyFieldName, null, null);
+                    typeCfg.AffinityKeyFieldName);
             }
             else
             {
@@ -467,7 +424,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                 int typeId = PortableUtils.TypeId(typeName, nameMapper, idMapper);
 
                 AddType(null, typeId, typeName, true, metaEnabled, keepDeserialized, nameMapper, idMapper, null,
-                    typeCfg.AffinityKeyFieldName, null, null);
+                    typeCfg.AffinityKeyFieldName);
             }
         }
 
@@ -482,21 +439,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                 ? PortableMarshalAwareSerializer.Instance 
                 : null;
         }
-
-        /// <summary>
-        /// Add predefined type.
-        /// </summary>
-        /// <param name="type">Type.</param>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="typedHandler">Typed handler.</param>
-        /// <param name="untypedHandler">Untyped handler.</param>
-        private void AddPredefinedType(Type type, int typeId, object typedHandler,
-            PortableSystemWriteDelegate untypedHandler)
-        {
-            AddType(type, typeId, GetTypeName(type), false, false, false, null, null, null, null, typedHandler,
-                untypedHandler);
-        }
-
+        
         /// <summary>
         /// Add type.
         /// </summary>
@@ -510,12 +453,9 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="idMapper">ID mapper.</param>
         /// <param name="serializer">Serializer.</param>
         /// <param name="affKeyFieldName">Affinity key field name.</param>
-        /// <param name="typedHandler">Typed handler.</param>
-        /// <param name="untypedHandler">Untyped handler.</param>
         private void AddType(Type type, int typeId, string typeName, bool userType, bool metaEnabled,
             bool keepDeserialized, IPortableNameMapper nameMapper, IPortableIdMapper idMapper,
-            IPortableSerializer serializer, string affKeyFieldName, object typedHandler,
-            PortableSystemWriteDelegate untypedHandler)
+            IPortableSerializer serializer, string affKeyFieldName)
         {
             long typeKey = PortableUtils.TypeKey(userType, typeId);
 
@@ -533,7 +473,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
             IPortableTypeDescriptor descriptor =
                 new PortableFullTypeDescriptor(type, typeId, typeName, userType, nameMapper, idMapper, serializer,
-                    metaEnabled, keepDeserialized, affKeyFieldName, typedHandler, untypedHandler);
+                    metaEnabled, keepDeserialized, affKeyFieldName);
 
             if (type != null)
                 _typeToDesc[type] = descriptor;
@@ -553,7 +493,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
             var serializer = new PortableSystemTypeSerializer<T>(ctor);
 
-            AddType(type, typeId, GetTypeName(type), false, false, false, null, null, serializer, null, null, null);
+            AddType(type, typeId, GetTypeName(type), false, false, false, null, null, serializer, null);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
index c8dcc5a..9842c46 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSurrogateTypeDescriptor.cs
@@ -117,17 +117,5 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             get { return null; }
         }
-
-        /** <inheritDoc /> */
-        public object TypedHandler
-        {
-            get { return null; }
-        }
-
-        /** <inheritDoc /> */
-        public PortableSystemWriteDelegate UntypedHandler
-        {
-            get { return null; }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
index 95a6ef8..4e67370 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableSystemHandlers.cs
@@ -47,195 +47,15 @@ namespace Apache.Ignite.Core.Impl.Portable
     internal static class PortableSystemHandlers
     {
         /** Write handlers. */
-        private static readonly Dictionary<Type, PortableSystemWriteDelegate> WriteHandlers =
+        private static volatile Dictionary<Type, PortableSystemWriteDelegate> _writeHandlers =
             new Dictionary<Type, PortableSystemWriteDelegate>();
 
+        /** Mutex for write handlers update. */
+        private static readonly Object WriteHandlersMux = new Object();
+
         /** 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;
 
@@ -256,32 +76,18 @@ namespace Apache.Ignite.Core.Impl.Portable
         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));
+            ReadHandlers[PortableUtils.TypeDate] = new PortableSystemReader<DateTime?>(s => PortableUtils.ReadDate(s, false));
 
             // 3. String.
             ReadHandlers[PortableUtils.TypeString] = new PortableSystemReader<string>(PortableUtils.ReadString);
@@ -292,11 +98,9 @@ namespace Apache.Ignite.Core.Impl.Portable
             // 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);
@@ -304,12 +108,9 @@ namespace Apache.Ignite.Core.Impl.Portable
             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);
@@ -336,12 +137,6 @@ namespace Apache.Ignite.Core.Impl.Portable
             // 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);
 
@@ -349,358 +144,249 @@ namespace Apache.Ignite.Core.Impl.Portable
             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)
+        /// <summary>
+        /// Try getting write handler for type.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static PortableSystemWriteDelegate GetWriteHandler(Type type)
         {
-            PortableSystemWriteDelegate handler;
+            PortableSystemWriteDelegate res;
 
-            if (WriteHandlers.TryGetValue(type, out handler))
-                return handler;
+            var writeHandlers0 = _writeHandlers;
 
-            // 1. Array?
-            if (type.IsArray)
+            // Have we ever met this type?
+            if (writeHandlers0 != null && writeHandlers0.TryGetValue(type, out res))
+                return res;
+            else
             {
-                if (type.GetElementType().IsEnum)
-                    return WriteEnumArray;
-                return WriteArray;
-            }
+                // Determine write handler for type and add it.
+                res = FindWriteHandler(type);
 
-            // 2. Enum?
-            if (type.IsEnum)
-                return WriteEnum;
-
-            // 3. Collection?
-            PortableCollectionInfo info = PortableCollectionInfo.Info(type);
+                if (res != null)
+                    AddWriteHandler(type, res);
 
-            if (info.IsAny)
-                return info.WriteHandler;
+                return res;
+            }
 
-            // No special handler found.
-            return null;
         }
 
         /// <summary>
-        /// Reads an object of predefined type.
+        /// Find write handler for 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;
+        /// <param name="type">Type.</param>
+        /// <returns>Write handler or NULL.</returns>
+        private static PortableSystemWriteDelegate FindWriteHandler(Type type)
+        {
+            // 1. Well-known types.
+            if (type == typeof (string))
+                return WriteString;
+            else if (type == typeof(decimal))
+                return WriteDecimal;
+            else if (type == typeof(DateTime))
+                return WriteDate;
+            else if (type == typeof(Guid))
+                return WriteGuid;
+            else if (type == typeof (PortableUserObject))
+                return WritePortable;
+            else if (type == typeof (ArrayList))
+                return WriteArrayList;
+            else if (type == typeof(Hashtable))
+                return WriteHashtable;
+            else if (type == typeof(DictionaryEntry))
+                return WriteMapEntry;
+            else if (type.IsArray)
+            {
+                // We know how to write any array type.
+                Type elemType = type.GetElementType();
+                
+                // Primitives.
+                if (elemType == typeof (bool))
+                    return WriteBoolArray;
+                else if (elemType == typeof(byte))
+                    return WriteByteArray;
+                else if (elemType == typeof(short))
+                    return WriteShortArray;
+                else if (elemType == typeof(char))
+                    return WriteCharArray;
+                else if (elemType == typeof(int))
+                    return WriteIntArray;
+                else if (elemType == typeof(long))
+                    return WriteLongArray;
+                else if (elemType == typeof(float))
+                    return WriteFloatArray;
+                else if (elemType == typeof(double))
+                    return WriteDoubleArray;
+                // Non-CLS primitives.
+                else if (elemType == typeof(sbyte))
+                    return WriteSbyteArray;
+                else if (elemType == typeof(ushort))
+                    return WriteUshortArray;
+                else if (elemType == typeof(uint))
+                    return WriteUintArray;
+                else if (elemType == typeof(ulong))
+                    return WriteUlongArray;
+                // Special types.
+                else if (elemType == typeof (decimal))
+                    return WriteDecimalArray;
+                else if (elemType == typeof(string))
+                    return WriteStringArray;
+//                else if (elemType == typeof(DateTime))
+//                    return WriteDateArray;
+                else if (elemType == typeof(DateTime?))
+                    return WriteNullableDateArray;
+//                else if (elemType == typeof(Guid))
+//                    return WriteGuidArray;
+                else if (elemType == typeof(Guid?))
+                    return WriteNullableGuidArray;
+                // Enums.
+                if (elemType.IsEnum)
+                    return WriteEnumArray;
+                
+                // Regular array.
+                return WriteArray;
+            }
+            else if (type.IsEnum)
+                // We know how to write enums.
+                return WriteEnum;
+            else
+            {
+                // We know how to write collections.
+                PortableCollectionInfo info = PortableCollectionInfo.Info(type);
 
-            ctx.Stream.WriteByte(PortableUtils.TypeInt);
-            ctx.Stream.WriteInt(*(int*)&val);
-        }
+                if (info.IsAny)
+                    return info.WriteHandler;
 
-        /**
-         * <summary>Write long.</summary>
-         */
-        private static void WriteLong(PortableWriterImpl ctx, object obj)
-        {
-            WriteLongTyped(ctx.Stream, (long)obj);
+                return null;
+            }
         }
 
-        /**
-         * <summary>Write long.</summary>
-         */
-        private static void WriteLongTyped(IPortableStream stream, long obj)
+        /// <summary>
+        /// Add write handler for type.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="handler"></param>
+        private static void AddWriteHandler(Type type, PortableSystemWriteDelegate handler)
         {
-            stream.WriteByte(PortableUtils.TypeLong);
-            stream.WriteLong(obj);
-        }
+            lock (WriteHandlersMux)
+            {
+                if (_writeHandlers == null)
+                {
+                    Dictionary<Type, PortableSystemWriteDelegate> writeHandlers0 = 
+                        new Dictionary<Type, PortableSystemWriteDelegate>();
 
-        /**
-         * <summary>Write ulong.</summary>
-         */
-        private static unsafe void WriteUlong(PortableWriterImpl ctx, object obj)
-        {
-            ulong val = (ulong)obj;
+                    writeHandlers0[type] = handler;
 
-            ctx.Stream.WriteByte(PortableUtils.TypeLong);
-            ctx.Stream.WriteLong(*(long*)&val);
-        }
+                    _writeHandlers = writeHandlers0;
+                }
+                else if (!_writeHandlers.ContainsKey(type))
+                {
+                    Dictionary<Type, PortableSystemWriteDelegate> writeHandlers0 =
+                        new Dictionary<Type, PortableSystemWriteDelegate>(_writeHandlers);
 
-        /**
-         * <summary>Write float.</summary>
-         */
-        private static void WriteFloat(PortableWriterImpl ctx, object obj)
-        {
-            WriteFloatTyped(ctx.Stream, (float)obj);
-        }
+                    writeHandlers0[type] = handler;
 
-        /**
-         * <summary>Write float.</summary>
-         */
-        private static void WriteFloatTyped(IPortableStream stream, float obj)
-        {
-            stream.WriteByte(PortableUtils.TypeFloat);
-            stream.WriteFloat(obj);
+                    _writeHandlers = writeHandlers0;
+                }
+            }
         }
 
-        /**
-         * <summary>Write double.</summary>
-         */
-        private static void WriteDouble(PortableWriterImpl ctx, object obj)
+        /// <summary>
+        /// Reads an object of predefined type.
+        /// </summary>
+        public static T ReadSystemType<T>(byte typeId, PortableReaderImpl ctx)
         {
-            WriteDoubleTyped(ctx.Stream, (double)obj);
-        }
+            var handler = ReadHandlers[typeId];
 
-        /**
-         * <summary>Write double.</summary>
-         */
-        private static void WriteDoubleTyped(IPortableStream stream, double obj)
-        {
-            stream.WriteByte(PortableUtils.TypeDouble);
-            stream.WriteDouble(obj);
+            Debug.Assert(handler != null, "Cannot find predefined read handler: " + typeId);
+            
+            return handler.Read<T>(ctx);
         }
-
-        /**
-         * <summary>Write decimal.</summary>
-         */
+        
+        /// <summary>
+        /// Write decimal.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeDecimal);
 
-            PortableUtils.WriteDecimal(obj, stream);
+            PortableUtils.WriteDecimal((decimal)obj, ctx.Stream);
         }
-
-        /**
-         * <summary>Write date.</summary>
-         */
+        
+        /// <summary>
+        /// Write date.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteDate(PortableWriterImpl ctx, object obj)
         {
-            WriteDateTyped(ctx.Stream, (DateTime?)obj);
-        }
+            ctx.Stream.WriteByte(PortableUtils.TypeDate);
 
-        /**
-         * <summary>Write double.</summary>
-         */
-        private static void WriteDateTyped(IPortableStream stream, DateTime? obj)
-        {
-            stream.WriteByte(PortableUtils.TypeDate);
-
-            PortableUtils.WriteDate(obj, stream);
+            PortableUtils.WriteDate((DateTime)obj, ctx.Stream);
         }
-
-        /**
-         * <summary>Write string.</summary>
-         */
+        
+        /// <summary>
+        /// Write string.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Object.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeString);
 
-            PortableUtils.WriteString(obj, stream);
+            PortableUtils.WriteString((string)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write Guid.</summary>
-         */
+        /// <summary>
+        /// Write Guid.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteGuid(PortableWriterImpl ctx, object obj)
         {
-            WriteGuidTyped(ctx.Stream, (Guid?)obj);
-        }
+            ctx.Stream.WriteByte(PortableUtils.TypeGuid);
 
-        /**
-         * <summary>Write Guid.</summary>
-         */
-        private static void WriteGuidTyped(IPortableStream stream, Guid? obj)
-        {
-            stream.WriteByte(PortableUtils.TypeGuid);
-
-            PortableUtils.WriteGuid(obj, stream);
+            PortableUtils.WriteGuid((Guid)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write bool array.</summary>
-         */
+        /// <summary>
+        /// Write boolaen array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteBoolArray(PortableWriterImpl ctx, object obj)
         {
-            WriteBoolArrayTyped(ctx.Stream, (bool[])obj);
-        }
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayBool);
 
-        /**
-         * <summary>Write bool array.</summary>
-         */
-        private static void WriteBoolArrayTyped(IPortableStream stream, bool[] obj)
-        {
-            stream.WriteByte(PortableUtils.TypeArrayBool);
-
-            PortableUtils.WriteBooleanArray(obj, stream);
+            PortableUtils.WriteBooleanArray((bool[])obj, ctx.Stream);
         }
-
-        /**
-         * <summary>Write byte array.</summary>
-         */
+        
+        /// <summary>
+        /// Write byte array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayByte);
 
-            PortableUtils.WriteByteArray(obj, stream);
+            PortableUtils.WriteByteArray((byte[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write sbyte array.</summary>
-         */
+        /// <summary>
+        /// Write sbyte array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteSbyteArray(PortableWriterImpl ctx, object obj)
         {
             ctx.Stream.WriteByte(PortableUtils.TypeArrayByte);
@@ -708,27 +394,23 @@ namespace Apache.Ignite.Core.Impl.Portable
             PortableUtils.WriteByteArray((byte[])(Array)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write short array.</summary>
-         */
+        /// <summary>
+        /// Write short array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayShort);
 
-            PortableUtils.WriteShortArray(obj, stream);
+            PortableUtils.WriteShortArray((short[])obj, ctx.Stream);
         }
-
-        /**
-         * <summary>Write ushort array.</summary>
-         */
+        
+        /// <summary>
+        /// Write ushort array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteUshortArray(PortableWriterImpl ctx, object obj)
         {
             ctx.Stream.WriteByte(PortableUtils.TypeArrayShort);
@@ -736,45 +418,35 @@ namespace Apache.Ignite.Core.Impl.Portable
             PortableUtils.WriteShortArray((short[])(Array)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write char array.</summary>
-         */
+        /// <summary>
+        /// Write char array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayChar);
 
-            PortableUtils.WriteCharArray(obj, stream);
+            PortableUtils.WriteCharArray((char[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write int array.</summary>
-         */
+        /// <summary>
+        /// Write int array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayInt);
 
-            PortableUtils.WriteIntArray(obj, stream);
+            PortableUtils.WriteIntArray((int[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write uint array.</summary>
-         */
+        /// <summary>
+        /// Write uint array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteUintArray(PortableWriterImpl ctx, object obj)
         {
             ctx.Stream.WriteByte(PortableUtils.TypeArrayInt);
@@ -782,27 +454,23 @@ namespace Apache.Ignite.Core.Impl.Portable
             PortableUtils.WriteIntArray((int[])(Array)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write long array.</summary>
-         */
+        /// <summary>
+        /// Write long array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayLong);
 
-            PortableUtils.WriteLongArray(obj, stream);
+            PortableUtils.WriteLongArray((long[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write ulong array.</summary>
-         */
+        /// <summary>
+        /// Write ulong array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteUlongArray(PortableWriterImpl ctx, object obj)
         {
             ctx.Stream.WriteByte(PortableUtils.TypeArrayLong);
@@ -810,114 +478,102 @@ namespace Apache.Ignite.Core.Impl.Portable
             PortableUtils.WriteLongArray((long[])(Array)obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write float array.</summary>
-         */
+        /// <summary>
+        /// Write float array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayFloat);
 
-            PortableUtils.WriteFloatArray(obj, stream);
+            PortableUtils.WriteFloatArray((float[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write double array.</summary>
-         */
+        /// <summary>
+        /// Write double array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayDouble);
 
-            PortableUtils.WriteDoubleArray(obj, stream);
+            PortableUtils.WriteDoubleArray((double[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write decimal array.</summary>
-         */
+        /// <summary>
+        /// Write decimal array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayDecimal);
 
-            PortableUtils.WriteDecimalArray(obj, stream);
+            PortableUtils.WriteDecimalArray((decimal[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write date array.</summary>
-         */
+        /// <summary>
+        /// Write date array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteDateArray(PortableWriterImpl ctx, object obj)
         {
-            WriteDateArrayTyped(ctx.Stream, (DateTime?[])obj);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayDate);
+
+            PortableUtils.WriteDateArray((DateTime[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write date array.</summary>
-         */
-        private static void WriteDateArrayTyped(IPortableStream stream, DateTime?[] obj)
+        /// <summary>
+        /// Write nullable date array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
+        private static void WriteNullableDateArray(PortableWriterImpl ctx, object obj)
         {
-            stream.WriteByte(PortableUtils.TypeArrayDate);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayDate);
 
-            PortableUtils.WriteDateArray(obj, stream);
+            PortableUtils.WriteDateArray((DateTime?[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write string array.</summary>
-         */
+        /// <summary>
+        /// Write string array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         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);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayString);
 
-            PortableUtils.WriteStringArray(obj, stream);
+            PortableUtils.WriteStringArray((string[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write Guid array.</summary>
-         */
+        /// <summary>
+        /// Write GUID array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
         private static void WriteGuidArray(PortableWriterImpl ctx, object obj)
         {
-            WriteGuidArrayTyped(ctx.Stream, (Guid?[])obj);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayGuid);
+
+            PortableUtils.WriteGuidArray((Guid[])obj, ctx.Stream);
         }
 
-        /**
-         * <summary>Write Guid array.</summary>
-         */
-        private static void WriteGuidArrayTyped(IPortableStream stream, Guid?[] obj)
+        /// <summary>
+        /// Write nullable GUID array.
+        /// </summary>
+        /// <param name="ctx">Context.</param>
+        /// <param name="obj">Value.</param>
+        private static void WriteNullableGuidArray(PortableWriterImpl ctx, object obj)
         {
-            stream.WriteByte(PortableUtils.TypeArrayGuid);
+            ctx.Stream.WriteByte(PortableUtils.TypeArrayGuid);
 
-            PortableUtils.WriteGuidArray(obj, stream);
+            PortableUtils.WriteGuidArray((Guid?[])obj, ctx.Stream);
         }
-
+        
         /**
          * <summary>Write enum array.</summary>
          */
@@ -1025,17 +681,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
             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>

http://git-wip-us.apache.org/repos/asf/ignite/blob/f6111b55/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
index f926adc..546ccaa 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
@@ -251,6 +251,12 @@ namespace Apache.Ignite.Core.Impl.Portable
         /** Indicates object array. */
         public const int ObjTypeId = -1;
 
+        /** Length of tpye ID. */
+        public const int LengthTypeId = 1;
+
+        /** Length of array size. */
+        public const int LengthArraySize = 4;
+
         /** Int type. */
         public static readonly Type TypInt = typeof(int);
 
@@ -631,13 +637,12 @@ namespace Apache.Ignite.Core.Impl.Portable
          * <param name="val">Date.</param>
          * <param name="stream">Stream.</param>
          */
-        public static void WriteDate(DateTime? val, IPortableStream stream)
+        public static void WriteDate(DateTime val, IPortableStream stream)
         {
             long high;
             int low;
 
-            Debug.Assert(val.HasValue);
-            ToJavaDate(val.Value, out high, out low);
+            ToJavaDate(val, out high, out low);
 
             stream.WriteLong(high);
             stream.WriteInt(low);
@@ -657,11 +662,28 @@ namespace Apache.Ignite.Core.Impl.Portable
             return ToDotNetDate(high, low, local);
         }
 
-        /**
-         * <summary>Write date array.</summary>
-         * <param name="vals">Date array.</param>
-         * <param name="stream">Stream.</param>
-         */
+        /// <summary>
+        /// Write date array.
+        /// </summary>
+        /// <param name="vals">Values.</param>
+        /// <param name="stream">Stream.</param>
+        public static void WriteDateArray(DateTime[] vals, IPortableStream stream)
+        {
+            stream.WriteInt(vals.Length);
+
+            foreach (DateTime val in vals)
+            {
+                stream.WriteByte(TypeDate);
+
+                WriteDate(val, stream);
+            }
+        }
+
+        /// <summary>
+        /// Write nullable date array.
+        /// </summary>
+        /// <param name="vals">Values.</param>
+        /// <param name="stream">Stream.</param>
         public static void WriteDateArray(DateTime?[] vals, IPortableStream stream)
         {
             stream.WriteInt(vals.Length);
@@ -669,7 +691,11 @@ namespace Apache.Ignite.Core.Impl.Portable
             foreach (DateTime? val in vals)
             {
                 if (val.HasValue)
-                    PortableSystemHandlers.WriteHndDateTyped(stream, val);
+                {
+                    stream.WriteByte(TypeDate);
+
+                    WriteDate(val.Value, stream);
+                }
                 else
                     stream.WriteByte(HdrNull);
             }
@@ -727,7 +753,10 @@ namespace Apache.Ignite.Core.Impl.Portable
             foreach (string val in vals)
             {
                 if (val != null)
-                    PortableSystemHandlers.WriteHndStringTyped(stream, val); 
+                {
+                    stream.WriteByte(TypeString);
+                    WriteString(val, stream);
+                }
                 else
                     stream.WriteByte(HdrNull);
             }
@@ -960,10 +989,9 @@ namespace Apache.Ignite.Core.Impl.Portable
          * <param name="val">GUID.</param>
          * <param name="stream">Stream.</param>
          */
-        public static unsafe void WriteGuid(Guid? val, IPortableStream stream)
+        public static unsafe void WriteGuid(Guid val, IPortableStream stream)
         {
-            Debug.Assert(val.HasValue);
-            byte[] bytes = val.Value.ToByteArray();
+            byte[] bytes = val.ToByteArray();
 
             // .Net returns bytes in the following order: _a(4), _b(2), _c(2), _d, _e, _g, _h, _i, _j, _k.
             // And _a, _b and _c are always in little endian format irrespective of system configuration.
@@ -1050,11 +1078,28 @@ namespace Apache.Ignite.Core.Impl.Portable
             return new Guid(bytes);
         }
 
-        /**
-         * <summary>Write GUID array.</summary>
-         * <param name="vals">GUID array.</param>
-         * <param name="stream">Stream.</param>
-         */
+        /// <summary>
+        /// Write GUID array.
+        /// </summary>
+        /// <param name="vals">Values.</param>
+        /// <param name="stream">Stream.</param>
+        public static void WriteGuidArray(Guid[] vals, IPortableStream stream)
+        {
+            stream.WriteInt(vals.Length);
+
+            foreach (Guid val in vals)
+            {
+                stream.WriteByte(TypeGuid);
+
+                WriteGuid(val, stream);
+            }
+        }
+
+        /// <summary>
+        /// Write GUID array.
+        /// </summary>
+        /// <param name="vals">Values.</param>
+        /// <param name="stream">Stream.</param>
         public static void WriteGuidArray(Guid?[] vals, IPortableStream stream)
         {
             stream.WriteInt(vals.Length);
@@ -1062,7 +1107,11 @@ namespace Apache.Ignite.Core.Impl.Portable
             foreach (Guid? val in vals)
             {
                 if (val.HasValue)
-                    PortableSystemHandlers.WriteHndGuidTyped(stream, val);
+                {
+                    stream.WriteByte(TypeGuid);
+
+                    WriteGuid(val.Value, stream);
+                }
                 else
                     stream.WriteByte(HdrNull);
             }