You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2017/03/31 13:32:17 UTC

[4/5] ignite git commit: IGNITE-2703 .NET: Dynamic type registration

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/CallbacksTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/CallbacksTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/CallbacksTest.cs
new file mode 100644
index 0000000..a014205
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/CallbacksTest.cs
@@ -0,0 +1,369 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Binary.Serializable
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests that deserialization callbacks are invoked correctly.
+    /// </summary>
+    public class CallbacksTest
+    {
+        /** Deserialization messages. */
+        private static readonly List<string> Messages = new List<string>();
+
+        /// <summary>
+        /// Tests that callbacks are invoked in correct order on class with ISerializable interface.
+        /// </summary>
+        [Test]
+        public void TestSerializable()
+        {
+            CheckCallbacks<SerCallbacks>(true);
+        }
+
+        /// <summary>
+        /// Tests that callbacks are invoked in correct order on class without ISerializable interface.
+        /// </summary>
+        [Test]
+        public void TestNonSerializable()
+        {
+            CheckCallbacks<SerCallbacksNoInterface>(false);
+        }
+
+        /// <summary>
+        /// Tests that callbacks are invoked in correct order on class with ISerializable interface.
+        /// </summary>
+        [Test]
+        public void TestSerializableStruct()
+        {
+            var obj = new SerCallbacksStruct
+            {
+                Name = "Foo",
+                Inner = new SerCallbacksStruct
+                {
+                    Name = "Bar"
+                }
+            };
+
+            Messages.Clear();
+            var res = TestUtils.SerializeDeserialize(obj);
+
+            Assert.AreEqual("Foo", res.Name);
+            Assert.AreEqual("Bar", ((SerCallbacksStruct) res.Inner).Name);
+
+            // OnDeserialization callbacks should be called AFTER entire tree is deserialized.
+            // Other callbacks order is not strictly defined.
+            var expected = new[]
+            {
+                "Foo.OnSerializing",
+                "Bar.OnSerializing",
+                "Bar.OnSerialized",
+                "Foo.OnSerialized",
+                ".OnDeserializing",
+                ".OnDeserializing",
+                "Bar.ctor",
+                "Bar.OnDeserialized",
+                "Foo.ctor",
+                "Foo.OnDeserialized",
+                "Foo.OnDeserialization",
+                "Bar.OnDeserialization",
+            };
+
+            Assert.AreEqual(expected, Messages);
+        }
+
+        /// <summary>
+        /// Tests that callbacks are invoked in correct order on class without ISerializable interface.
+        /// </summary>
+        [Test]
+        public void TestNonSerializableStruct()
+        {
+            var obj = new SerCallbacksStructNoInterface
+            {
+                Name = "Foo",
+                Inner = new SerCallbacksStructNoInterface
+                {
+                    Name = "Bar"
+                }
+            };
+
+            Messages.Clear();
+            var res = TestUtils.SerializeDeserialize(obj);
+
+            Assert.AreEqual("Foo", res.Name);
+            Assert.AreEqual("Bar", ((SerCallbacksStructNoInterface) res.Inner).Name);
+
+            // OnDeserialization callbacks should be called AFTER entire tree is deserialized.
+            // Other callbacks order is not strictly defined.
+            var expected = new[]
+            {
+                "Foo.OnSerializing",
+                "Bar.OnSerializing",
+                "Bar.OnSerialized",
+                "Foo.OnSerialized",
+                ".OnDeserializing",
+                ".OnDeserializing",
+                "Bar.OnDeserialized",
+                "Foo.OnDeserialized",
+                "Foo.OnDeserialization",
+                "Bar.OnDeserialization",
+            };
+
+            Assert.AreEqual(expected, Messages);
+        }
+
+        /// <summary>
+        /// Checks the callbacks.
+        /// </summary>
+        private static void CheckCallbacks<T>(bool ctorCall) where T : SerCallbacksNoInterface, new()
+        {
+            var obj = new T
+            {
+                Name = "Foo",
+                Inner = new T
+                {
+                    Name = "Bar",
+                    Inner = new T
+                    {
+                        Name = "Baz"
+                    }
+                }
+            };
+
+            Messages.Clear();
+            var res = TestUtils.SerializeDeserialize(obj);
+
+            Assert.AreEqual("Foo", res.Name);
+            Assert.AreEqual("Bar", res.Inner.Name);
+            Assert.AreEqual("Baz", res.Inner.Inner.Name);
+
+            // OnDeserialization callbacks should be called AFTER entire tree is deserialized.
+            // Other callbacks order is not strictly defined.
+            var expected = new[]
+            {
+                "Foo.OnSerializing",
+                "Bar.OnSerializing",
+                "Baz.OnSerializing",
+                "Baz.OnSerialized",
+                "Bar.OnSerialized",
+                "Foo.OnSerialized",
+                ".OnDeserializing",
+                ".OnDeserializing",
+                ".OnDeserializing",
+                "Baz.ctor",
+                "Baz.OnDeserialized",
+                "Bar.ctor",
+                "Bar.OnDeserialized",
+                "Foo.ctor",
+                "Foo.OnDeserialized",
+                "Foo.OnDeserialization",
+                "Bar.OnDeserialization",
+                "Baz.OnDeserialization"
+            };
+
+            if (!ctorCall)
+                expected = expected.Where(x => !x.Contains("ctor")).ToArray();
+
+            Assert.AreEqual(expected, Messages);
+        }
+
+        /// <summary>
+        /// Tests that incorrect method signature causes a descriptive exception.
+        /// </summary>
+        [Test]
+        public void TestIncorrectMethodSignature()
+        {
+            var ex = Assert.Throws<TypeLoadException>(
+                    () => TestUtils.SerializeDeserialize(new InvalidCallbackSignature()));
+
+            var t = typeof(InvalidCallbackSignature);
+
+            Assert.AreEqual(string.Format("Type '{0}' in assembly '{1}' has method 'OnDeserializing' " +
+                                          "with an incorrect signature for the serialization attribute that it " +
+                                          "is decorated with.", t, t.Assembly), ex.Message);
+        }
+
+        /// <summary>
+        /// Class with serialization callbacks and <see cref="ISerializable" /> implemented.
+        /// This goes through <see cref="SerializableSerializer"/>.
+        /// </summary>
+        [Serializable]
+        private class SerCallbacks : SerCallbacksNoInterface, ISerializable
+        {
+            public SerCallbacks()
+            {
+            }
+
+            protected SerCallbacks(SerializationInfo info, StreamingContext context)
+            {
+                Name = info.GetString("name");
+                Inner = (SerCallbacks) info.GetValue("inner", typeof(SerCallbacks));
+
+                Messages.Add(string.Format("{0}.ctor", Name));
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("name", Name);
+                info.AddValue("inner", Inner);
+            }
+        }
+
+        /// <summary>
+        /// Class with serialization callbacks and without <see cref="ISerializable" /> implemented.
+        /// This goes through <see cref="BinaryReflectiveSerializer"/>.
+        /// </summary>
+        [Serializable]
+        private class SerCallbacksNoInterface : IDeserializationCallback
+        {
+            public string Name { get; set; }
+
+            public SerCallbacksNoInterface Inner { get; set; }
+
+            public void OnDeserialization(object sender)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialization", Name));
+            }
+
+            [OnSerializing]
+            public void OnSerializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerializing", Name));
+            }
+
+            [OnSerialized]
+            public void OnSerialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerialized", Name));
+            }
+
+            [OnDeserializing]
+            public void OnDeserializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserializing", Name));
+            }
+
+            [OnDeserialized]
+            public void OnDeserialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialized", Name));
+            }
+        }
+
+        private class InvalidCallbackSignature
+        {
+            [OnDeserializing]
+            public void OnDeserializing()
+            {
+                // No-op.
+            }
+        }
+
+        [Serializable]
+        private struct SerCallbacksStruct : IDeserializationCallback, ISerializable
+        {
+            public string Name { get; set; }
+
+            public object Inner { get; set; }
+
+            public SerCallbacksStruct(SerializationInfo info, StreamingContext context) : this()
+            {
+                Name = info.GetString("name");
+                Inner = info.GetValue("inner", typeof(object));
+                Messages.Add(string.Format("{0}.ctor", Name));
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("name", Name);
+                info.AddValue("inner", Inner);
+            }
+
+            public void OnDeserialization(object sender)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialization", Name));
+            }
+
+            [OnSerializing]
+            public void OnSerializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerializing", Name));
+            }
+
+            [OnSerialized]
+            public void OnSerialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerialized", Name));
+            }
+
+            [OnDeserializing]
+            public void OnDeserializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserializing", Name));
+            }
+
+            [OnDeserialized]
+            public void OnDeserialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialized", Name));
+            }
+        }
+
+        private struct SerCallbacksStructNoInterface : IDeserializationCallback
+        {
+            public string Name { get; set; }
+
+            public object Inner { get; set; }
+
+            public void OnDeserialization(object sender)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialization", Name));
+            }
+
+            [OnSerializing]
+            public void OnSerializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerializing", Name));
+            }
+
+            [OnSerialized]
+            public void OnSerialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnSerialized", Name));
+            }
+
+            [OnDeserializing]
+            public void OnDeserializing(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserializing", Name));
+            }
+
+            [OnDeserialized]
+            public void OnDeserialized(StreamingContext context)
+            {
+                Messages.Add(string.Format("{0}.OnDeserialized", Name));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/DelegatesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/DelegatesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/DelegatesTest.cs
new file mode 100644
index 0000000..90720d4
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/DelegatesTest.cs
@@ -0,0 +1,161 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Binary.Serializable
+{
+    using System;
+    using System.Reflection;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests delegate serialization.
+    /// </summary>
+    public class DelegatesTest
+    {
+        /** Test int value. */
+        private static int _int;
+
+        /** Test delegate. */
+        private delegate string LowerSubStringDelegate(string s, int startIndex);
+
+        /// <summary>
+        /// Tests that delegates can be serialized.
+        /// </summary>
+        [Test]
+        public void TestAction()
+        {
+            // Action with captured variable.
+            var val = new PrimitivesTest.Primitives {Int = 135};
+
+            Action act = () => {
+                val.Int++;
+                _int = val.Int;
+            };
+
+            var res = TestUtils.SerializeDeserialize(act);
+            Assert.AreEqual(act.Method, res.Method);
+            Assert.AreNotEqual(act.Target, res.Target);
+
+            res();
+            Assert.AreEqual(135, val.Int);   // Captured variable is deserialized to a new instance.
+            Assert.AreEqual(136, _int);
+
+            // Action with arguments.
+            Action<PrimitivesTest.Primitives, int> act1 = (p, i) => { p.Int = i; };
+
+            var res1 = TestUtils.SerializeDeserialize(act1);
+            Assert.AreEqual(act1.Method, res1.Method);
+
+            res1(val, 33);
+            Assert.AreEqual(33, val.Int);
+        }
+
+        /// <summary>
+        /// Tests that anonymous function can be serialized.
+        /// </summary>
+        [Test]
+        public void TestFunc()
+        {
+            int ms = DateTime.Now.Millisecond;
+
+            Func<int, int> func = x => x + ms;
+
+            var resFunc = TestUtils.SerializeDeserialize(func);
+            Assert.AreEqual(func.Method, resFunc.Method);
+            Assert.AreNotEqual(func.Target, resFunc.Target);
+
+            Assert.AreEqual(ms + 20, resFunc(20));
+        }
+
+        /// <summary>
+        /// Tests that old-fashioned delegate can be serialized.
+        /// </summary>
+        [Test]
+        public void TestDelegate()
+        {
+            // Delegate to a static method.
+            LowerSubStringDelegate del1 = LowerSubString;
+
+            var del1Res = TestUtils.SerializeDeserialize(del1);
+
+            Assert.AreEqual(del1.Method, del1Res.Method);
+            Assert.IsNull(del1Res.Target);
+
+            Assert.AreEqual("ooz", del1Res("FOOZ", 1));
+
+            // Delegate to an anonymous method.
+            LowerSubStringDelegate del2 = (s, i) => s.Substring(i).ToLower();
+
+            var del2Res = TestUtils.SerializeDeserialize(del2);
+
+            Assert.AreEqual(del2.Method, del2Res.Method, "Delegate methods are same");
+
+            Assert.AreEqual("ooz", del2Res("FOOZ", 1), "Delegate works as expected");
+        }
+
+        /// <summary>
+        /// Tests that MethodInfo can be serialized.
+        /// </summary>
+        [Test]
+        public void TestMethodInfo()
+        {
+            var methods = typeof(string).GetMethods(BindingFlags.Public | BindingFlags.NonPublic
+                                                    | BindingFlags.Instance | BindingFlags.Static);
+
+            Assert.IsNotEmpty(methods);
+
+            foreach (var methodInfo in methods)
+            {
+                var res = TestUtils.SerializeDeserialize(methodInfo);
+
+                Assert.AreEqual(methodInfo.Name, res.Name);
+                Assert.AreEqual(methodInfo.DeclaringType, res.DeclaringType);
+                Assert.AreEqual(methodInfo.ReturnType, res.ReturnType);
+                Assert.AreEqual(methodInfo.GetParameters(), res.GetParameters());
+            }
+        }
+
+        /// <summary>
+        /// Tests that recursive anonymous function can be serialized.
+        /// </summary>
+        [Test]
+        public void TestRecursiveFunc()
+        {
+            Func<int, int> fib = null;
+            fib = x => x == 0
+                ? 0
+                : x == 1
+                    ? 1
+                    : fib(x - 2) + fib(x - 1);
+
+            Assert.AreEqual(89, fib(11));
+            Assert.AreEqual(144, fib(12));
+
+            var resFib = TestUtils.SerializeDeserialize(fib);
+
+            Assert.AreEqual(fib.Method, resFib.Method);
+
+            Assert.AreEqual(89, resFib(11));
+            Assert.AreEqual(144, resFib(12));
+        }
+
+        private static string LowerSubString(string s, int startIndex)
+        {
+            return s.Substring(startIndex).ToLower();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/ObjectReferenceTests.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/ObjectReferenceTests.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/ObjectReferenceTests.cs
new file mode 100644
index 0000000..71d2f9a
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/ObjectReferenceTests.cs
@@ -0,0 +1,131 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Binary.Serializable
+{
+    using System;
+    using System.Runtime.Serialization;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests that <see cref="IObjectReference"/> objects are deserialized properly.
+    /// This only applies to <see cref="ISerializable"/> implementers, which can replace underlying object
+    /// with <see cref="SerializationInfo.SetType"/>, <see cref="SerializationInfo.AssemblyName"/>, and
+    /// <see cref="SerializationInfo.FullTypeName"/>.
+    /// </summary>
+    public class ObjectReferenceTests
+    {
+        /// <summary>
+        /// Tests serialization object replacement with <see cref="SerializationInfo.SetType"/> method.
+        /// </summary>
+        [Test]
+        public void TestSetType()
+        {
+            var obj = new SetTypeReplacer(25);
+
+            var res = TestUtils.SerializeDeserialize(obj);
+
+            Assert.AreEqual(obj.Value, res.Value);
+        }
+
+        /// <summary>
+        /// Tests serialization object replacement with <see cref="SerializationInfo.FullTypeName"/> property.
+        /// </summary>
+        [Test]
+        public void TestTypeName()
+        {
+            var obj = new TypeNameReplacer(36);
+
+            var res = TestUtils.SerializeDeserialize(obj);
+
+            Assert.AreEqual(obj.Value, res.Value);
+        }
+
+        [Serializable]
+        private class SetTypeReplacer : ISerializable
+        {
+            private readonly int _value;
+
+            public SetTypeReplacer(int value)
+            {
+                _value = value;
+            }
+
+            public int Value
+            {
+                get { return _value; }
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.SetType(typeof(ObjectInfoHolder));
+
+                info.AddValue("type", GetType());
+                info.AddValue("val", Value);
+            }
+        }
+
+        [Serializable]
+        private class TypeNameReplacer : ISerializable
+        {
+            private readonly int _value;
+
+            public TypeNameReplacer(int value)
+            {
+                _value = value;
+            }
+
+            public int Value
+            {
+                get { return _value; }
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.FullTypeName = typeof(ObjectInfoHolder).FullName;
+                info.AssemblyName = typeof(ObjectInfoHolder).Assembly.FullName;
+
+                info.AddValue("type", GetType());
+                info.AddValue("val", Value);
+            }
+        }
+
+        [Serializable]
+        private class ObjectInfoHolder : IObjectReference, ISerializable
+        {
+            public Type ObjectType { get; set; }
+
+            public int Value { get; set; }
+
+            public object GetRealObject(StreamingContext context)
+            {
+                return Activator.CreateInstance(ObjectType, Value);
+            }
+
+            public ObjectInfoHolder(SerializationInfo info, StreamingContext context)
+            {
+                ObjectType = (Type) info.GetValue("type", typeof(Type));
+                Value = info.GetInt32("val");
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                // No-op.
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/PrimitivesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/PrimitivesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/PrimitivesTest.cs
new file mode 100644
index 0000000..bbbee60
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/PrimitivesTest.cs
@@ -0,0 +1,754 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ReSharper disable StringLiteralTypo
+// ReSharper disable IdentifierTypo
+namespace Apache.Ignite.Core.Tests.Binary.Serializable
+{
+    using System;
+    using System.Linq;
+    using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Binary;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests [Serializable] mechanism handling primitive types.
+    /// </summary>
+    public class PrimitivesTest
+    {
+        /** */
+        private IIgnite _ignite;
+        
+        /// <summary>
+        /// Sets up the test fixture.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            _ignite = Ignition.Start(TestUtils.GetTestConfiguration());
+        }
+
+        /// <summary>
+        /// Tears down the test fixture.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the DateTime which is ISerializable struct.
+        /// </summary>
+        [Test]
+        public void TestDateTime()
+        {
+            var marsh = GetMarshaller();
+
+            var val = DateTime.Now;
+
+            Assert.AreEqual(val, marsh.Unmarshal<DateTime>(marsh.Marshal(val)));
+
+            Assert.AreEqual(new[] {val}, marsh.Unmarshal<DateTime[]>(marsh.Marshal(new[] {val})));
+
+            Assert.AreEqual(new DateTime?[] {val, null},
+                marsh.Unmarshal<DateTime?[]>(marsh.Marshal(new DateTime?[] {val, null})));
+        }
+
+        /// <summary>
+        /// Tests that primitive types can be serialized with ISerializable mechanism.
+        /// </summary>
+        [Test]
+        public void TestPrimitives()
+        {
+            var marsh = GetMarshaller();
+
+            var val1 = new Primitives
+            {
+                Byte = 1,
+                Bytes = new byte[] {2, 3, byte.MinValue, byte.MaxValue},
+                Sbyte = -64,
+                Sbytes = new sbyte[] {sbyte.MinValue, sbyte.MaxValue, 1, 2, -4, -5},
+                Bool = true,
+                Bools = new[] {true, true, false},
+                Char = 'x',
+                Chars = new[] {'a', 'z', char.MinValue, char.MaxValue},
+                Short = -25,
+                Shorts = new short[] {5, -7, 9, short.MinValue, short.MaxValue},
+                Ushort = 99,
+                Ushorts = new ushort[] {10, 20, 12, ushort.MinValue, ushort.MaxValue},
+                Int = -456,
+                Ints = new[] {-100, 200, -300, int.MinValue, int.MaxValue},
+                Uint = 456,
+                Uints = new uint[] {100, 200, 300, uint.MinValue, uint.MaxValue},
+                Long = long.MaxValue,
+                Longs = new[] {long.MinValue, long.MaxValue, 33, -44},
+                Ulong = ulong.MaxValue,
+                Ulongs = new ulong[] {ulong.MinValue, ulong.MaxValue, 33},
+                Float = 1.33f,
+                Floats = new[]
+                {
+                    float.MinValue, float.MaxValue,
+                    float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN,
+                    1.23f, -2.5f
+                },
+                Double = -6.78,
+                Doubles = new[]
+                {
+                    double.MinValue, double.MaxValue, double.Epsilon,
+                    double.NegativeInfinity, double.PositiveInfinity,
+                    3.76, -9.89
+                },
+                Decimal = 1.23456789m,
+                Decimals = new[]
+                {
+                    decimal.MinValue, decimal.MaxValue, decimal.One, decimal.MinusOne, decimal.Zero,
+                    1.35m, -2.46m
+                },
+                DateTime = DateTime.UtcNow,
+                DateTimes = new[] {DateTime.Now, DateTime.MinValue, DateTime.MaxValue, DateTime.UtcNow},
+                Guid = Guid.NewGuid(),
+                Guids = new[] {Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()},
+                String = "hello world",
+                Strings = new[] {"hello", "world"}
+            };
+
+            var vals = new[] {new Primitives(), val1};
+
+            foreach (var val in vals)
+            {
+                Assert.IsFalse(val.GetObjectDataCalled);
+                Assert.IsFalse(val.SerializationCtorCalled);
+
+                // Unmarshal in full and binary form.
+                var bytes = marsh.Marshal(val);
+                var res = marsh.Unmarshal<Primitives>(bytes);
+                var bin = marsh.Unmarshal<IBinaryObject>(bytes, BinaryMode.ForceBinary);
+
+                // Verify flags.
+                Assert.IsTrue(val.GetObjectDataCalled);
+                Assert.IsFalse(val.SerializationCtorCalled);
+
+                Assert.IsFalse(res.GetObjectDataCalled);
+                Assert.IsTrue(res.SerializationCtorCalled);
+
+                // Verify values.
+                Assert.AreEqual(val.Byte, res.Byte);
+                Assert.AreEqual(val.Byte, bin.GetField<byte>("byte"));
+
+                Assert.AreEqual(val.Bytes, res.Bytes);
+                Assert.AreEqual(val.Bytes, bin.GetField<byte[]>("bytes"));
+
+                Assert.AreEqual(val.Sbyte, res.Sbyte);
+                Assert.AreEqual(val.Sbyte, bin.GetField<sbyte>("sbyte"));
+
+                Assert.AreEqual(val.Sbytes, res.Sbytes);
+                Assert.AreEqual(val.Sbytes, bin.GetField<sbyte[]>("sbytes"));
+
+                Assert.AreEqual(val.Bool, res.Bool);
+                Assert.AreEqual(val.Bool, bin.GetField<bool>("bool"));
+
+                Assert.AreEqual(val.Bools, res.Bools);
+                Assert.AreEqual(val.Bools, bin.GetField<bool[]>("bools"));
+
+                Assert.AreEqual(val.Char, res.Char);
+                Assert.AreEqual(val.Char, bin.GetField<char>("char"));
+
+                Assert.AreEqual(val.Chars, res.Chars);
+                Assert.AreEqual(val.Chars, bin.GetField<char[]>("chars"));
+
+                Assert.AreEqual(val.Short, res.Short);
+                Assert.AreEqual(val.Short, bin.GetField<short>("short"));
+
+                Assert.AreEqual(val.Shorts, res.Shorts);
+                Assert.AreEqual(val.Shorts, bin.GetField<short[]>("shorts"));
+
+                Assert.AreEqual(val.Ushort, res.Ushort);
+                Assert.AreEqual(val.Ushort, bin.GetField<ushort>("ushort"));
+
+                Assert.AreEqual(val.Ushorts, res.Ushorts);
+                Assert.AreEqual(val.Ushorts, bin.GetField<ushort[]>("ushorts"));
+
+                Assert.AreEqual(val.Int, res.Int);
+                Assert.AreEqual(val.Int, bin.GetField<int>("int"));
+
+                Assert.AreEqual(val.Ints, res.Ints);
+                Assert.AreEqual(val.Ints, bin.GetField<int[]>("ints"));
+
+                Assert.AreEqual(val.Uint, res.Uint);
+                Assert.AreEqual(val.Uint, bin.GetField<uint>("uint"));
+
+                Assert.AreEqual(val.Uints, res.Uints);
+                Assert.AreEqual(val.Uints, bin.GetField<uint[]>("uints"));
+
+                Assert.AreEqual(val.Long, res.Long);
+                Assert.AreEqual(val.Long, bin.GetField<long>("long"));
+
+                Assert.AreEqual(val.Longs, res.Longs);
+                Assert.AreEqual(val.Longs, bin.GetField<long[]>("longs"));
+
+                Assert.AreEqual(val.Ulong, res.Ulong);
+                Assert.AreEqual(val.Ulong, bin.GetField<ulong>("ulong"));
+
+                Assert.AreEqual(val.Ulongs, res.Ulongs);
+                Assert.AreEqual(val.Ulongs, bin.GetField<ulong[]>("ulongs"));
+
+                Assert.AreEqual(val.Float, res.Float);
+                Assert.AreEqual(val.Float, bin.GetField<float>("float"));
+
+                Assert.AreEqual(val.Floats, res.Floats);
+                Assert.AreEqual(val.Floats, bin.GetField<float[]>("floats"));
+
+                Assert.AreEqual(val.Double, res.Double);
+                Assert.AreEqual(val.Double, bin.GetField<double>("double"));
+
+                Assert.AreEqual(val.Doubles, res.Doubles);
+                Assert.AreEqual(val.Doubles, bin.GetField<double[]>("doubles"));
+
+                Assert.AreEqual(val.Decimal, res.Decimal);
+                Assert.AreEqual(val.Decimal, bin.GetField<decimal>("decimal"));
+
+                Assert.AreEqual(val.Decimals, res.Decimals);
+                Assert.AreEqual(val.Decimals, bin.GetField<decimal[]>("decimals"));
+
+                Assert.AreEqual(val.Guid, res.Guid);
+                Assert.AreEqual(val.Guid, bin.GetField<Guid>("guid"));
+
+                Assert.AreEqual(val.Guids, res.Guids);
+                Assert.AreEqual(val.Guids, bin.GetField<Guid[]>("guids"));
+
+                Assert.AreEqual(val.DateTime, res.DateTime);
+                Assert.AreEqual(val.DateTime, bin.GetField<IBinaryObject>("datetime").Deserialize<DateTime>());
+
+                Assert.AreEqual(val.DateTimes, res.DateTimes);
+                var dts = bin.GetField<IBinaryObject[]>("datetimes");
+                Assert.AreEqual(val.DateTimes, dts == null ? null : dts.Select(x => x.Deserialize<DateTime>()));
+
+                Assert.AreEqual(val.String, res.String);
+                Assert.AreEqual(val.String, bin.GetField<string>("string"));
+
+                Assert.AreEqual(val.Strings, res.Strings);
+                Assert.AreEqual(val.Strings, bin.GetField<string[]>("strings"));
+
+                VerifyFieldTypes(bin);
+            }
+        }
+
+        /// <summary>
+        /// Tests that primitive types in nullable form can be serialized with ISerializable mechanism.
+        /// </summary>
+        [Test]
+        public void TestPrimitivesNullable()
+        {
+            var marsh = GetMarshaller();
+
+            var val1 = new PrimitivesNullable
+            {
+                Byte = 1,
+                Bytes = new byte?[] {2, 3, byte.MinValue, byte.MaxValue, null},
+                Sbyte = -64,
+                Sbytes = new sbyte?[] {sbyte.MinValue, sbyte.MaxValue, 1, 2, -4, -5, null},
+                Bool = true,
+                Bools = new bool?[] {true, true, false, null},
+                Char = 'x',
+                Chars = new char?[] {'a', 'z', char.MinValue, char.MaxValue, null},
+                Short = -25,
+                Shorts = new short?[] {5, -7, 9, short.MinValue, short.MaxValue, null},
+                Ushort = 99,
+                Ushorts = new ushort?[] {10, 20, 12, ushort.MinValue, ushort.MaxValue, null},
+                Int = -456,
+                Ints = new int?[] {-100, 200, -300, int.MinValue, int.MaxValue, null},
+                Uint = 456,
+                Uints = new uint?[] {100, 200, 300, uint.MinValue, uint.MaxValue, null},
+                Long = long.MaxValue,
+                Longs = new long?[] {long.MinValue, long.MaxValue, 33, -44, null},
+                Ulong = ulong.MaxValue,
+                Ulongs = new ulong?[] {ulong.MinValue, ulong.MaxValue, 33, null},
+                Float = 1.33f,
+                Floats = new float?[]
+                {
+                    float.MinValue, float.MaxValue,
+                    float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN,
+                    1.23f, -2.5f, null
+                },
+                Double = -6.78,
+                Doubles = new double?[]
+                {
+                    double.MinValue, double.MaxValue, double.Epsilon,
+                    double.NegativeInfinity, double.PositiveInfinity,
+                    3.76, -9.89, null
+                },
+                Decimal = 1.23456789m,
+                Decimals = new decimal?[]
+                {
+                    decimal.MinValue, decimal.MaxValue, decimal.One, decimal.MinusOne, decimal.Zero,
+                    1.35m, -2.46m, null
+                },
+                DateTime = DateTime.UtcNow,
+                DateTimes = new DateTime?[]
+                {
+                    DateTime.Now, DateTime.MinValue, DateTime.MaxValue, DateTime.UtcNow, null
+                },
+                Guid = Guid.NewGuid(),
+                Guids = new Guid?[] {Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), null},
+            };
+
+            var vals = new[] {new PrimitivesNullable(), val1};
+
+            foreach (var val in vals)
+            {
+                Assert.IsFalse(val.GetObjectDataCalled);
+                Assert.IsFalse(val.SerializationCtorCalled);
+
+                // Unmarshal in full and binary form.
+                var bytes = marsh.Marshal(val);
+                var res = marsh.Unmarshal<PrimitivesNullable>(bytes);
+                var bin = marsh.Unmarshal<IBinaryObject>(bytes, BinaryMode.ForceBinary);
+
+                // Verify flags.
+                Assert.IsTrue(val.GetObjectDataCalled);
+                Assert.IsFalse(val.SerializationCtorCalled);
+
+                Assert.IsFalse(res.GetObjectDataCalled);
+                Assert.IsTrue(res.SerializationCtorCalled);
+
+                // Verify values.
+                Assert.AreEqual(val.Byte, res.Byte);
+                Assert.AreEqual(val.Byte, bin.GetField<byte?>("byte"));
+
+                Assert.AreEqual(val.Bytes, res.Bytes);
+                Assert.AreEqual(val.Bytes, bin.GetField<byte?[]>("bytes"));
+
+                Assert.AreEqual(val.Sbyte, res.Sbyte);
+                Assert.AreEqual(val.Sbyte, bin.GetField<sbyte?>("sbyte"));
+
+                Assert.AreEqual(val.Sbytes, res.Sbytes);
+                Assert.AreEqual(val.Sbytes, bin.GetField<sbyte?[]>("sbytes"));
+
+                Assert.AreEqual(val.Bool, res.Bool);
+                Assert.AreEqual(val.Bool, bin.GetField<bool?>("bool"));
+
+                Assert.AreEqual(val.Bools, res.Bools);
+                Assert.AreEqual(val.Bools, bin.GetField<bool?[]>("bools"));
+
+                Assert.AreEqual(val.Char, res.Char);
+                Assert.AreEqual(val.Char, bin.GetField<char?>("char"));
+
+                Assert.AreEqual(val.Chars, res.Chars);
+                Assert.AreEqual(val.Chars, bin.GetField<char?[]>("chars"));
+
+                Assert.AreEqual(val.Short, res.Short);
+                Assert.AreEqual(val.Short, bin.GetField<short?>("short"));
+
+                Assert.AreEqual(val.Shorts, res.Shorts);
+                Assert.AreEqual(val.Shorts, bin.GetField<short?[]>("shorts"));
+
+                Assert.AreEqual(val.Ushort, res.Ushort);
+                Assert.AreEqual(val.Ushort, bin.GetField<ushort?>("ushort"));
+
+                Assert.AreEqual(val.Ushorts, res.Ushorts);
+                Assert.AreEqual(val.Ushorts, bin.GetField<ushort?[]>("ushorts"));
+
+                Assert.AreEqual(val.Int, res.Int);
+                Assert.AreEqual(val.Int, bin.GetField<int?>("int"));
+
+                Assert.AreEqual(val.Ints, res.Ints);
+                Assert.AreEqual(val.Ints, bin.GetField<int?[]>("ints"));
+
+                Assert.AreEqual(val.Uint, res.Uint);
+                Assert.AreEqual(val.Uint, bin.GetField<uint?>("uint"));
+
+                Assert.AreEqual(val.Uints, res.Uints);
+                Assert.AreEqual(val.Uints, bin.GetField<uint?[]>("uints"));
+
+                Assert.AreEqual(val.Long, res.Long);
+                Assert.AreEqual(val.Long, bin.GetField<long?>("long"));
+
+                Assert.AreEqual(val.Longs, res.Longs);
+                Assert.AreEqual(val.Longs, bin.GetField<long?[]>("longs"));
+
+                Assert.AreEqual(val.Ulong, res.Ulong);
+                Assert.AreEqual(val.Ulong, bin.GetField<ulong?>("ulong"));
+
+                Assert.AreEqual(val.Ulongs, res.Ulongs);
+                Assert.AreEqual(val.Ulongs, bin.GetField<ulong?[]>("ulongs"));
+
+                Assert.AreEqual(val.Float, res.Float);
+                Assert.AreEqual(val.Float, bin.GetField<float?>("float"));
+
+                Assert.AreEqual(val.Floats, res.Floats);
+                Assert.AreEqual(val.Floats, bin.GetField<float?[]>("floats"));
+
+                Assert.AreEqual(val.Double, res.Double);
+                Assert.AreEqual(val.Double, bin.GetField<double?>("double"));
+
+                Assert.AreEqual(val.Doubles, res.Doubles);
+                Assert.AreEqual(val.Doubles, bin.GetField<double?[]>("doubles"));
+
+                Assert.AreEqual(val.Decimal, res.Decimal);
+                Assert.AreEqual(val.Decimal, bin.GetField<decimal?>("decimal"));
+
+                Assert.AreEqual(val.Decimals, res.Decimals);
+                Assert.AreEqual(val.Decimals, bin.GetField<decimal?[]>("decimals"));
+
+                Assert.AreEqual(val.Guid, res.Guid);
+                Assert.AreEqual(val.Guid, bin.GetField<Guid?>("guid"));
+
+                Assert.AreEqual(val.Guids, res.Guids);
+                Assert.AreEqual(val.Guids, bin.GetField<Guid?[]>("guids"));
+
+                Assert.AreEqual(val.DateTime, res.DateTime);
+                var dt = bin.GetField<IBinaryObject>("datetime");
+                Assert.AreEqual(val.DateTime, dt == null ? null : dt.Deserialize<DateTime?>());
+
+                Assert.AreEqual(val.DateTimes, res.DateTimes);
+                var dts = bin.GetField<IBinaryObject[]>("datetimes");
+                Assert.AreEqual(val.DateTimes, dts == null
+                    ? null
+                    : dts.Select(x => x == null ? null : x.Deserialize<DateTime?>()));
+            }
+        }
+
+        /// <summary>
+        /// Verifies the field types.
+        /// </summary>
+        private static void VerifyFieldTypes(IBinaryObject bin)
+        {
+            var binType = bin.GetBinaryType();
+            
+            Assert.AreEqual("byte", binType.GetFieldTypeName("byte"));
+            Assert.AreEqual("byte", binType.GetFieldTypeName("sbyte"));
+            
+            Assert.AreEqual("byte[]", binType.GetFieldTypeName("bytes"));
+            Assert.AreEqual("byte[]", binType.GetFieldTypeName("sbytes"));
+            
+            Assert.AreEqual("boolean", binType.GetFieldTypeName("bool"));
+            Assert.AreEqual("boolean[]", binType.GetFieldTypeName("bools"));
+            
+            Assert.AreEqual("char", binType.GetFieldTypeName("char"));
+            Assert.AreEqual("char[]", binType.GetFieldTypeName("chars"));
+
+            Assert.AreEqual("short", binType.GetFieldTypeName("short"));
+            Assert.AreEqual("short[]", binType.GetFieldTypeName("shorts"));
+
+            Assert.AreEqual("short", binType.GetFieldTypeName("ushort"));
+            Assert.AreEqual("short[]", binType.GetFieldTypeName("ushorts"));
+
+            Assert.AreEqual("int", binType.GetFieldTypeName("int"));
+            Assert.AreEqual("int[]", binType.GetFieldTypeName("ints"));
+
+            Assert.AreEqual("int", binType.GetFieldTypeName("uint"));
+            Assert.AreEqual("int[]", binType.GetFieldTypeName("uints"));
+
+            Assert.AreEqual("long", binType.GetFieldTypeName("long"));
+            Assert.AreEqual("long[]", binType.GetFieldTypeName("longs"));
+
+            Assert.AreEqual("long", binType.GetFieldTypeName("ulong"));
+            Assert.AreEqual("long[]", binType.GetFieldTypeName("ulongs"));
+
+            Assert.AreEqual("float", binType.GetFieldTypeName("float"));
+            Assert.AreEqual("float[]", binType.GetFieldTypeName("floats"));
+
+            Assert.AreEqual("double", binType.GetFieldTypeName("double"));
+            Assert.AreEqual("double[]", binType.GetFieldTypeName("doubles"));
+
+            Assert.AreEqual("decimal", binType.GetFieldTypeName("decimal"));
+            Assert.AreEqual("Object", binType.GetFieldTypeName("decimals"));
+
+            Assert.AreEqual("UUID", binType.GetFieldTypeName("guid"));
+            Assert.AreEqual("Object", binType.GetFieldTypeName("guids"));
+
+            Assert.AreEqual("Object", binType.GetFieldTypeName("datetime"));
+            Assert.AreEqual("Object", binType.GetFieldTypeName("datetimes"));
+        }
+
+        /// <summary>
+        /// Gets the marshaller.
+        /// </summary>
+        private Marshaller GetMarshaller()
+        {
+            return ((Ignite) _ignite).Marshaller;
+        }
+
+        [Serializable]
+        public class Primitives : ISerializable
+        {
+            public bool GetObjectDataCalled { get; private set; }
+            public bool SerializationCtorCalled { get; private set; }
+
+            public byte Byte { get; set; }
+            public byte[] Bytes { get; set; }
+            public sbyte Sbyte { get; set; }
+            public sbyte[] Sbytes { get; set; }
+            public bool Bool { get; set; }
+            public bool[] Bools { get; set; }
+            public char Char { get; set; }
+            public char[] Chars { get; set; }
+            public short Short { get; set; }
+            public short[] Shorts { get; set; }
+            public ushort Ushort { get; set; }
+            public ushort[] Ushorts { get; set; }
+            public int Int { get; set; }
+            public int[] Ints { get; set; }
+            public uint Uint { get; set; }
+            public uint[] Uints { get; set; }
+            public long Long { get; set; }
+            public long[] Longs { get; set; }
+            public ulong Ulong { get; set; }
+            public ulong[] Ulongs { get; set; }
+            public float Float { get; set; }
+            public float[] Floats { get; set; }
+            public double Double { get; set; }
+            public double[] Doubles { get; set; }
+            public decimal Decimal { get; set; }
+            public decimal[] Decimals { get; set; }
+            public Guid Guid { get; set; }
+            public Guid[] Guids { get; set; }
+            public DateTime DateTime { get; set; }
+            public DateTime[] DateTimes { get; set; }
+            public string String { get; set; }
+            public string[] Strings { get; set; }
+
+            public Primitives()
+            {
+                // No-op.
+            }
+
+            protected Primitives(SerializationInfo info, StreamingContext context)
+            {
+                SerializationCtorCalled = true;
+
+                Byte = info.GetByte("byte");
+                Bytes = (byte[]) info.GetValue("bytes", typeof(byte[]));
+
+                Sbyte = info.GetSByte("sbyte");
+                Sbytes = (sbyte[]) info.GetValue("sbytes", typeof(sbyte[]));
+
+                Bool = info.GetBoolean("bool");
+                Bools = (bool[]) info.GetValue("bools", typeof(bool[]));
+
+                Char = info.GetChar("char");
+                Chars = (char[]) info.GetValue("chars", typeof(char[]));
+
+                Short = info.GetInt16("short");
+                Shorts = (short[]) info.GetValue("shorts", typeof(short[]));
+
+                Ushort = info.GetUInt16("ushort");
+                Ushorts = (ushort[]) info.GetValue("ushorts", typeof(ushort[]));
+
+                Int = info.GetInt32("int");
+                Ints = (int[]) info.GetValue("ints", typeof(int[]));
+
+                Uint = info.GetUInt32("uint");
+                Uints = (uint[]) info.GetValue("uints", typeof(uint[]));
+
+                Long = info.GetInt64("long");
+                Longs = (long[]) info.GetValue("longs", typeof(long[]));
+
+                Ulong = info.GetUInt64("ulong");
+                Ulongs = (ulong[]) info.GetValue("ulongs", typeof(ulong[]));
+
+                Float = info.GetSingle("float");
+                Floats = (float[]) info.GetValue("floats", typeof(float[]));
+
+                Double = info.GetDouble("double");
+                Doubles = (double[]) info.GetValue("doubles", typeof(double[]));
+
+                Decimal = info.GetDecimal("decimal");
+                Decimals = (decimal[]) info.GetValue("decimals", typeof(decimal[]));
+
+                Guid = (Guid) info.GetValue("guid", typeof(Guid));
+                Guids = (Guid[]) info.GetValue("guids", typeof(Guid[]));
+
+                DateTime = info.GetDateTime("datetime");
+                DateTimes = (DateTime[]) info.GetValue("datetimes", typeof(DateTime[]));
+
+                String = info.GetString("string");
+                Strings = (string[]) info.GetValue("strings", typeof(string[]));
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                GetObjectDataCalled = true;
+
+                info.AddValue("byte", Byte);
+                info.AddValue("bytes", Bytes, typeof(byte[]));
+                info.AddValue("sbyte", Sbyte);
+                info.AddValue("sbytes", Sbytes, typeof(sbyte[]));
+                info.AddValue("bool", Bool);
+                info.AddValue("bools", Bools, typeof(bool[]));
+                info.AddValue("char", Char);
+                info.AddValue("chars", Chars, typeof(char[]));
+                info.AddValue("short", Short);
+                info.AddValue("shorts", Shorts, typeof(short[]));
+                info.AddValue("ushort", Ushort);
+                info.AddValue("ushorts", Ushorts, typeof(ushort[]));
+                info.AddValue("int", Int);
+                info.AddValue("ints", Ints, typeof(int[]));
+                info.AddValue("uint", Uint);
+                info.AddValue("uints", Uints, typeof(uint[]));
+                info.AddValue("long", Long);
+                info.AddValue("longs", Longs, typeof(long[]));
+                info.AddValue("ulong", Ulong);
+                info.AddValue("ulongs", Ulongs, typeof(ulong[]));
+                info.AddValue("float", Float);
+                info.AddValue("floats", Floats, typeof(float[]));
+                info.AddValue("double", Double);
+                info.AddValue("doubles", Doubles, typeof(double[]));
+                info.AddValue("decimal", Decimal);
+                info.AddValue("decimals", Decimals, typeof(decimal[]));
+                info.AddValue("guid", Guid);
+                info.AddValue("guids", Guids, typeof(Guid[]));
+                info.AddValue("datetime", DateTime);
+                info.AddValue("datetimes", DateTimes, typeof(DateTime[]));
+                info.AddValue("string", String, typeof(string));
+                info.AddValue("strings", Strings, typeof(string[]));
+            }
+        }
+
+        [Serializable]
+        private class PrimitivesNullable : ISerializable
+        {
+            public bool GetObjectDataCalled { get; private set; }
+            public bool SerializationCtorCalled { get; private set; }
+
+            public byte? Byte { get; set; }
+            public byte?[] Bytes { get; set; }
+            public sbyte? Sbyte { get; set; }
+            public sbyte?[] Sbytes { get; set; }
+            public bool? Bool { get; set; }
+            public bool?[] Bools { get; set; }
+            public char? Char { get; set; }
+            public char?[] Chars { get; set; }
+            public short? Short { get; set; }
+            public short?[] Shorts { get; set; }
+            public ushort? Ushort { get; set; }
+            public ushort?[] Ushorts { get; set; }
+            public int? Int { get; set; }
+            public int?[] Ints { get; set; }
+            public uint? Uint { get; set; }
+            public uint?[] Uints { get; set; }
+            public long? Long { get; set; }
+            public long?[] Longs { get; set; }
+            public ulong? Ulong { get; set; }
+            public ulong?[] Ulongs { get; set; }
+            public float? Float { get; set; }
+            public float?[] Floats { get; set; }
+            public double? Double { get; set; }
+            public double?[] Doubles { get; set; }
+            public decimal? Decimal { get; set; }
+            public decimal?[] Decimals { get; set; }
+            public Guid? Guid { get; set; }
+            public Guid?[] Guids { get; set; }
+            public DateTime? DateTime { get; set; }
+            public DateTime?[] DateTimes { get; set; }
+
+            public PrimitivesNullable()
+            {
+                // No-op.
+            }
+
+            protected PrimitivesNullable(SerializationInfo info, StreamingContext context)
+            {
+                SerializationCtorCalled = true;
+
+                Byte = (byte?) info.GetValue("byte", typeof(byte?));
+                Bytes = (byte?[]) info.GetValue("bytes", typeof(byte?[]));
+
+                Sbyte = (sbyte?) info.GetValue("sbyte", typeof(sbyte?));
+                Sbytes = (sbyte?[]) info.GetValue("sbytes", typeof(sbyte?[]));
+
+                Bool = (bool?) info.GetValue("bool", typeof(bool?));
+                Bools = (bool?[]) info.GetValue("bools", typeof(bool?[]));
+
+                Char = (char?) info.GetValue("char", typeof(char?));
+                Chars = (char?[]) info.GetValue("chars", typeof(char?[]));
+
+                Short = (short?) info.GetValue("short", typeof(short?));
+                Shorts = (short?[]) info.GetValue("shorts", typeof(short?[]));
+
+                Ushort = (ushort?) info.GetValue("ushort", typeof(ushort?));
+                Ushorts = (ushort?[]) info.GetValue("ushorts", typeof(ushort?[]));
+
+                Int = (int?) info.GetValue("int", typeof(int?));
+                Ints = (int?[]) info.GetValue("ints", typeof(int?[]));
+
+                Uint = (uint?) info.GetValue("uint", typeof(uint?));
+                Uints = (uint?[]) info.GetValue("uints", typeof(uint?[]));
+
+                Long = (long?) info.GetValue("long", typeof(long?));
+                Longs = (long?[]) info.GetValue("longs", typeof(long?[]));
+
+                Ulong = (ulong?) info.GetValue("ulong", typeof(ulong?));
+                Ulongs = (ulong?[]) info.GetValue("ulongs", typeof(ulong?[]));
+
+                Float = (float?) info.GetValue("float", typeof(float?));
+                Floats = (float?[]) info.GetValue("floats", typeof(float?[]));
+
+                Double = (double?) info.GetValue("double", typeof(double?));
+                Doubles = (double?[]) info.GetValue("doubles", typeof(double?[]));
+
+                Decimal = (decimal?) info.GetValue("decimal", typeof(decimal?));
+                Decimals = (decimal?[]) info.GetValue("decimals", typeof(decimal?[]));
+
+                Guid = (Guid?) info.GetValue("guid", typeof(Guid?));
+                Guids = (Guid?[]) info.GetValue("guids", typeof(Guid?[]));
+
+                DateTime = (DateTime?) info.GetValue("datetime", typeof(DateTime?));
+                DateTimes = (DateTime?[]) info.GetValue("datetimes", typeof(DateTime?[]));
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                GetObjectDataCalled = true;
+
+                info.AddValue("byte", Byte, typeof(object));
+                info.AddValue("bytes", Bytes, typeof(object));
+                info.AddValue("sbyte", Sbyte, typeof(object));
+                info.AddValue("sbytes", Sbytes, typeof(object));
+                info.AddValue("bool", Bool, typeof(object));
+                info.AddValue("bools", Bools, typeof(object));
+                info.AddValue("char", Char, typeof(object));
+                info.AddValue("chars", Chars, typeof(object));
+                info.AddValue("short", Short, typeof(object));
+                info.AddValue("shorts", Shorts, typeof(object));
+                info.AddValue("ushort", Ushort, typeof(object));
+                info.AddValue("ushorts", Ushorts, typeof(object));
+                info.AddValue("int", Int, typeof(object));
+                info.AddValue("ints", Ints, typeof(object));
+                info.AddValue("uint", Uint, typeof(object));
+                info.AddValue("uints", Uints, typeof(object));
+                info.AddValue("long", Long, typeof(object));
+                info.AddValue("longs", Longs, typeof(object));
+                info.AddValue("ulong", Ulong, typeof(object));
+                info.AddValue("ulongs", Ulongs, typeof(object));
+                info.AddValue("float", Float, typeof(object));
+                info.AddValue("floats", Floats, typeof(object));
+                info.AddValue("double", Double, typeof(object));
+                info.AddValue("doubles", Doubles, typeof(object));
+                info.AddValue("decimal", Decimal, typeof(object));
+                info.AddValue("decimals", Decimals, typeof(object));
+                info.AddValue("guid", Guid, typeof(object));
+                info.AddValue("guids", Guids, typeof(object));
+                info.AddValue("datetime", DateTime, typeof(object));
+                info.AddValue("datetimes", DateTimes, typeof(object));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
new file mode 100644
index 0000000..b59247e
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/SqlDmlTest.cs
@@ -0,0 +1,277 @@
+\ufeff/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ReSharper disable UnusedMember.Local
+// ReSharper disable UnusedParameter.Local
+namespace Apache.Ignite.Core.Tests.Binary.Serializable
+{
+    using System;
+    using System.IO;
+    using System.Linq;
+    using System.Runtime.Serialization;
+    using System.Text;
+    using System.Threading;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache.Configuration;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Linq;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests SQL and DML with Serializable types.
+    /// </summary>
+    public class SqlDmlTest
+    {
+        /** */
+        private IIgnite _ignite;
+        
+        /** */
+        private StringBuilder _outSb;
+
+        /// <summary>
+        /// Sets up the test fixture.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            _outSb = new StringBuilder();
+            Console.SetError(new StringWriter(_outSb));
+
+            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
+            {
+                BinaryConfiguration = new BinaryConfiguration(typeof(SimpleSerializable))
+            };
+
+            _ignite = Ignition.Start(cfg);
+        }
+
+        /// <summary>
+        /// Tears down the test fixture.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the simple serializable.
+        /// </summary>
+        [Test]
+        public void TestSimpleSerializable()
+        {
+            var cache = _ignite.CreateCache<int, SimpleSerializable>(
+                new CacheConfiguration("simple", new QueryEntity(typeof(int), typeof(SimpleSerializable))));
+
+            cache[1] = new SimpleSerializable
+            {
+                String = "abc"
+            };
+            cache[2] = new SimpleSerializable
+            {
+                Byte = 25,
+                Bool = true,
+                Short = 66,
+                Int = 2,
+                Long = 98,
+                Float = 2.25f,
+                Double = 1.123,
+                Decimal = 5.67m,
+                Guid = Guid.NewGuid(),
+                String = "bar2"
+            };
+
+            // Test SQL.
+            var res = cache.Query(new SqlQuery(typeof(SimpleSerializable), "where Int = 2")).GetAll().Single();
+
+            Assert.AreEqual(2, res.Key);
+            Assert.AreEqual(2, res.Value.Int);
+            Assert.AreEqual("bar2", res.Value.String);
+
+            // Test DML.
+            var guid = Guid.NewGuid();
+            var insertRes = cache.QueryFields(new SqlFieldsQuery(
+                "insert into SimpleSerializable(_key, Byte, Bool, Short, Int, Long, Float, Double, " +
+                "Decimal, Guid, String) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", 
+                3, 45, true, 43, 33, 99, 4.5f, 6.7, 9.04m, guid, "bar33")).GetAll();
+
+            Assert.AreEqual(1, insertRes.Count);
+            Assert.AreEqual(1, insertRes[0][0]);
+
+            var dmlRes = cache[3];
+            Assert.AreEqual(45, dmlRes.Byte);
+            Assert.AreEqual(true, dmlRes.Bool);
+            Assert.AreEqual(43, dmlRes.Short);
+            Assert.AreEqual(33, dmlRes.Int);
+            Assert.AreEqual(99, dmlRes.Long);
+            Assert.AreEqual(4.5f, dmlRes.Float);
+            Assert.AreEqual(6.7, dmlRes.Double);
+            Assert.AreEqual(9.04m, dmlRes.Decimal);
+            Assert.AreEqual(guid, dmlRes.Guid);
+            Assert.AreEqual("bar33", dmlRes.String);
+        }
+
+        /// <summary>
+        /// Tests the .NET specific serializable.
+        /// </summary>
+        [Test]
+        public void TestDotNetSpecificSerializable()
+        {
+            var cache = _ignite.CreateCache<int, DotNetSpecificSerializable>(new CacheConfiguration("dotnet-ser",
+                new QueryEntity(typeof(int), typeof(DotNetSpecificSerializable))));
+
+            cache[1] = new DotNetSpecificSerializable(uint.MaxValue);
+            Assert.AreEqual(uint.MaxValue, cache[1].Uint);
+
+            // Test SQL.
+            var sqlRes = cache.QueryFields(new SqlFieldsQuery(
+                "select uint from DotNetSpecificSerializable where uint <> 0")).GetAll();
+
+            Assert.AreEqual(1, sqlRes.Count);
+            Assert.AreEqual(uint.MaxValue, (uint) (int) sqlRes[0][0]);
+
+            // Test LINQ.
+            var linqRes = cache.AsCacheQueryable().Select(x => x.Value.Uint).Single();
+            Assert.AreEqual(uint.MaxValue, linqRes);
+
+            // Test DML.
+            var dmlRes = cache.QueryFields(new SqlFieldsQuery(
+                "insert into DotNetSpecificSerializable(_key, uint) values (?, ?), (?, ?)",
+                2, uint.MaxValue, 3, 88)).GetAll();
+            Assert.AreEqual(1, dmlRes.Count);
+
+            Assert.AreEqual(88, cache[3].Uint);  // Works when value is in int range.
+
+            var ex = Assert.Throws<OverflowException>(() => cache.Get(2));  // Fails when out of int range.
+            Assert.AreEqual("Value was either too large or too small for a UInt32.", ex.Message);
+        }
+
+        /// <summary>
+        /// Tests the log warning.
+        /// </summary>
+        [Test]
+        public void TestLogWarning()
+        {
+            Thread.Sleep(10);  // Wait for logger update.
+
+            var expected =
+                string.Format("[WARN ][main][Marshaller] Type '{0}' implements '{1}'. " +
+                              "It will be written in Ignite binary format, however, " +
+                              "the following limitations apply: DateTime fields would not work in SQL; " +
+                              "sbyte, ushort, uint, ulong fields would not work in DML.",
+                    typeof(SimpleSerializable), typeof(ISerializable));
+
+            Assert.IsTrue(_outSb.ToString().Contains(expected));
+        }
+
+        /// <summary>
+        /// Serializable with Java-compatible fields.
+        /// </summary>
+        private class SimpleSerializable : ISerializable
+        {
+            [QuerySqlField]
+            public byte Byte { get; set; }
+
+            [QuerySqlField]
+            public bool Bool { get; set; }
+
+            [QuerySqlField]
+            public short Short { get; set; }
+            
+            [QuerySqlField]
+            public int Int { get; set; }
+            
+            [QuerySqlField]
+            public long Long { get; set; }
+            
+            [QuerySqlField]
+            public float Float { get; set; }
+            
+            [QuerySqlField]
+            public double Double { get; set; }
+            
+            [QuerySqlField]
+            public decimal Decimal { get; set; }
+            
+            [QuerySqlField]
+            public Guid Guid { get; set; }
+            
+            [QuerySqlField]
+            public string String { get; set; }
+
+            public SimpleSerializable()
+            {
+                // No-op.
+            }
+
+            public SimpleSerializable(SerializationInfo info, StreamingContext context)
+            {
+                Byte = info.GetByte("Byte");
+                Bool = info.GetBoolean("Bool");
+                Short = info.GetInt16("Short");
+                Int = info.GetInt32("Int");
+                Long = info.GetInt64("Long");
+                Float = info.GetSingle("Float");
+                Double = info.GetDouble("Double");
+                Decimal = info.GetDecimal("Decimal");
+                Guid = (Guid) info.GetValue("Guid", typeof(Guid));
+                String = info.GetString("String");
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("Byte", Byte);
+                info.AddValue("Bool", Bool);
+                info.AddValue("Short", Short);
+                info.AddValue("Int", Int);
+                info.AddValue("Long", Long);
+                info.AddValue("Float", Float);
+                info.AddValue("Double", Double);
+                info.AddValue("Decimal", Decimal);
+                info.AddValue("Guid", Guid);
+                info.AddValue("String", String);
+            }
+        }
+
+        /// <summary>
+        /// Serializable with incompatible fields.
+        /// </summary>
+        private class DotNetSpecificSerializable : ISerializable
+        {
+            /// <summary>
+            /// Uint is not supported in Java.
+            /// </summary>
+            [QuerySqlField]
+            public uint Uint { get; set; }
+
+            public DotNetSpecificSerializable(uint u)
+            {
+                Uint = u;
+            }
+
+            public DotNetSpecificSerializable(SerializationInfo info, StreamingContext context)
+            {
+                Uint = info.GetUInt32("uint");
+            }
+
+            public void GetObjectData(SerializationInfo info, StreamingContext context)
+            {
+                info.AddValue("uint", Uint);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
index 9348449..a3e6252 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Affinity/AffinityFunctionTest.cs
@@ -233,21 +233,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
         }
 
         /// <summary>
-        /// Tests the error on non-serializable function.
-        /// </summary>
-        [Test]
-        public void TestNonSerializableFunction()
-        {
-            var ex = Assert.Throws<IgniteException>(() =>
-                _ignite.CreateCache<int, int>(new CacheConfiguration("failCache")
-                {
-                    AffinityFunction = new NonSerializableAffinityFunction()
-                }));
-
-            Assert.AreEqual(ex.Message, "AffinityFunction should be serializable.");
-        }
-
-        /// <summary>
         /// Tests the exception propagation.
         /// </summary>
         [Test]
@@ -388,12 +373,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Affinity
             }
         }
 
-        private class NonSerializableAffinityFunction : SimpleAffinityFunction
-        {
-            // No-op.
-        }
-
-        [Serializable]
         private class FailInGetPartitionAffinityFunction : IAffinityFunction
         {
             public int Partitions

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
index f97741a..ce0441d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
@@ -232,9 +232,19 @@ namespace Apache.Ignite.Core.Tests.Cache
     /// <summary>
     /// Non-serializable processor.
     /// </summary>
-    public class NonSerializableCacheEntryProcessor : AddArgCacheEntryProcessor
+    public class NonSerializableCacheEntryProcessor : AddArgCacheEntryProcessor, IBinarizable
     {
-        // No-op.
+        /** <inheritdoc /> */
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            throw new Exception("ExpectedException");
+        }
+
+        /** <inheritdoc /> */
+        public void ReadBinary(IBinaryReader reader)
+        {
+            throw new Exception("ExpectedException");
+        }
     }
 
     /// <summary>
@@ -269,9 +279,19 @@ namespace Apache.Ignite.Core.Tests.Cache
     /// <summary>
     /// Non-serializable exception.
     /// </summary>
-    public class NonSerializableException : Exception
+    public class NonSerializableException : Exception, IBinarizable
     {
-        // No-op
+        /** <inheritdoc /> */
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            throw new Exception("ExpectedException");
+        }
+
+        /** <inheritdoc /> */
+        public void ReadBinary(IBinaryReader reader)
+        {
+            throw new Exception("ExpectedException");
+        }
     }
 
     /// <summary>
@@ -2356,15 +2376,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             TestInvoke<AddArgCacheEntryProcessor>(async);
             TestInvoke<BinarizableAddArgCacheEntryProcessor>(async);
 
-            try
-            {
-                TestInvoke<NonSerializableCacheEntryProcessor>(async);
-                Assert.Fail();
-            }
-            catch (BinaryObjectException)
-            {
-                // Expected
-            }
+            Assert.Throws<Exception>(() => TestInvoke<NonSerializableCacheEntryProcessor>(async));
         }
 
         private void TestInvoke<T>(bool async) where T: AddArgCacheEntryProcessor, new()
@@ -2396,7 +2408,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             AssertThrowsCacheEntryProcessorException(
                 () => cache.Invoke(key, new T {ThrowErrBinarizable = true}, arg));
             AssertThrowsCacheEntryProcessorException(
-                () => cache.Invoke(key, new T { ThrowErrNonSerializable = true }, arg), "BinaryObjectException");
+                () => cache.Invoke(key, new T { ThrowErrNonSerializable = true }, arg), "ExpectedException");
         }
 
         private static void AssertThrowsCacheEntryProcessorException(Action action, string containsText = null)
@@ -2417,7 +2429,8 @@ namespace Apache.Ignite.Core.Tests.Cache
                     Assert.AreEqual(AddArgCacheEntryProcessor.ExceptionText, ex.InnerException.Message);
                 }
                 else
-                    Assert.IsTrue(ex.ToString().Contains(containsText));
+                    Assert.IsTrue(ex.ToString().Contains(containsText), 
+                        "Expected: " + containsText + ", actual: " + ex);
             }
         }
 
@@ -2439,16 +2452,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             {
                 TestInvokeAll<AddArgCacheEntryProcessor>(async, i);
                 TestInvokeAll<BinarizableAddArgCacheEntryProcessor>(async, i);
-
-                try
-                {
-                    TestInvokeAll<NonSerializableCacheEntryProcessor>(async, i);
-                    Assert.Fail();
-                }
-                catch (BinaryObjectException)
-                {
-                    // Expected
-                }
+                Assert.Throws<Exception>(() => TestInvokeAll<NonSerializableCacheEntryProcessor>(async, i));
             }
         }
 
@@ -2493,7 +2497,7 @@ namespace Apache.Ignite.Core.Tests.Cache
             TestInvokeAllException(cache, entries, new T { ThrowErrBinarizable = true, ThrowOnKey = errKey }, 
                 arg, errKey);
             TestInvokeAllException(cache, entries, new T { ThrowErrNonSerializable = true, ThrowOnKey = errKey },
-                arg, errKey, "BinaryObjectException");
+                arg, errKey, "ExpectedException");
 
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
index fc47f52..d6705d4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
@@ -55,7 +55,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         [TestFixtureSetUp]
         public void StartGrids()
         {
-            TestUtils.JvmDebug = true;
             TestUtils.KillProcesses();
 
             IgniteConfiguration cfg = new IgniteConfiguration
@@ -867,8 +866,16 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
     /// <summary>
     /// Filter that can't be serialized.
     /// </summary>
-    public class InvalidScanQueryFilter<TV> : ScanQueryFilter<TV>
+    public class InvalidScanQueryFilter<TV> : ScanQueryFilter<TV>, IBinarizable
     {
-        // No-op.
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            throw new BinaryObjectException("Expected");
+        }
+
+        public void ReadBinary(IBinaryReader reader)
+        {
+            throw new BinaryObjectException("Expected");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryAbstractTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryAbstractTest.cs
index e890198..3c0633d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryAbstractTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryAbstractTest.cs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#pragma warning disable 618
 namespace Apache.Ignite.Core.Tests.Cache.Query.Continuous
 {
     using System;
@@ -1108,9 +1109,19 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Continuous
         /// <summary>
         /// Filter which cannot be serialized.
         /// </summary>
-        public class LocalFilter : AbstractFilter<BinarizableEntry>
+        public class LocalFilter : AbstractFilter<BinarizableEntry>, IBinarizable
         {
-            // No-op.
+            /** <inheritDoc /> */
+            public void WriteBinary(IBinaryWriter writer)
+            {
+                throw new BinaryObjectException("Expected");
+            }
+
+            /** <inheritDoc /> */
+            public void ReadBinary(IBinaryReader reader)
+            {
+                throw new BinaryObjectException("Expected");
+            }
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
index 4b13b9f..76241d2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs
@@ -23,7 +23,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Store
     using System.Linq;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Cache.Store;
+    using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl;
     using NUnit.Framework;
 
@@ -107,9 +109,6 @@ namespace Apache.Ignite.Core.Tests.Cache.Store
             for (int i = 105; i < 110; i++)
                 Assert.AreEqual("val_" + i, cache.Get(i));
 
-            // Test invalid filter
-            Assert.Throws<BinaryObjectException>(() => cache.LoadCache(new InvalidCacheEntryFilter(), 100, 10));
-
             // Test exception in filter
             Assert.Throws<CacheStoreException>(() => cache.LoadCache(new ExceptionalEntryFilter(), 100, 10));
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
index e82e238..3ef9ad0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -911,10 +911,12 @@ namespace Apache.Ignite.Core.Tests.Compute
             Assert.AreEqual(1, res.GetField<int>("field"));
 
             // This call must fail because "keepBinary" flag is reset.
-            Assert.Catch(typeof(BinaryObjectException), () =>
+            var ex = Assert.Throws<BinaryObjectException>(() =>
             {
                 compute.ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinarizableJava);
             });
+
+            Assert.AreEqual("Unknown pair [platformId=1, typeId=2009791293]", ex.Message);
         }
 
         /// <summary>
@@ -1386,9 +1388,17 @@ namespace Apache.Ignite.Core.Tests.Compute
         }
     }
 
-    class InvalidNetSimpleJob : NetSimpleJob
+    class InvalidNetSimpleJob : NetSimpleJob, IBinarizable
     {
-        // No-op.
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            throw new BinaryObjectException("Expected");
+        }
+
+        public void ReadBinary(IBinaryReader reader)
+        {
+            throw new BinaryObjectException("Expected");
+        }
     }
 
     [Serializable]
@@ -1460,9 +1470,17 @@ namespace Apache.Ignite.Core.Tests.Compute
         }
     }
 
-    class InvalidComputeAction : ComputeAction
+    class InvalidComputeAction : ComputeAction, IBinarizable
     {
-        // No-op.
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            throw new BinaryObjectException("Expected");
+        }
+
+        public void ReadBinary(IBinaryReader reader)
+        {
+            throw new BinaryObjectException("Expected");
+        }
     }
 
     interface IUserInterface<out T>

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
index 912102c..21cd263 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/IgniteExceptionTaskSelfTest.cs
@@ -88,9 +88,7 @@ namespace Apache.Ignite.Core.Tests.Compute
         {
             Mode = ErrorMode.MapJobNotMarshalable;
 
-            var e = ExecuteWithError() as BinaryObjectException;
-
-            Assert.IsNotNull(e);
+            Assert.IsInstanceOf<BinaryObjectException>(ExecuteWithError());
         }
 
         /// <summary>
@@ -168,13 +166,7 @@ namespace Apache.Ignite.Core.Tests.Compute
         {
             Mode = ErrorMode.RmtJobErrNotMarshalable;
 
-            int res = Execute();
-
-            Assert.AreEqual(1, res);
-
-            Assert.AreEqual(4, JobErrs.Count);
-
-            Assert.IsNotNull(JobErrs.ElementAt(0) as IgniteException);
+            Assert.Throws<SerializationException>(() => Execute());
         }
 
         /// <summary>
@@ -566,7 +558,7 @@ namespace Apache.Ignite.Core.Tests.Compute
         /// <summary>
         /// 
         /// </summary>
-        public class BadJob : IComputeJob<object>
+        public class BadJob : IComputeJob<object>, IBinarizable
         {
             [InstanceResource]
 
@@ -581,6 +573,18 @@ namespace Apache.Ignite.Core.Tests.Compute
             {
                 // No-op.
             }
+
+            /** <inheritDoc /> */
+            public void WriteBinary(IBinaryWriter writer)
+            {
+                throw new BinaryObjectException("Expected");
+            }
+
+            /** <inheritDoc /> */
+            public void ReadBinary(IBinaryReader reader)
+            {
+                throw new BinaryObjectException("Expected");
+            }
         }
 
         /// <summary>
@@ -621,7 +625,7 @@ namespace Apache.Ignite.Core.Tests.Compute
         /// <summary>
         /// 
         /// </summary>
-        public class BadJobResult
+        public class BadJobResult : IBinarizable
         {
             /** */
             public bool Rmt;
@@ -634,6 +638,18 @@ namespace Apache.Ignite.Core.Tests.Compute
             {
                 Rmt = rmt;
             }
+
+            /** <inheritDoc /> */
+            public void WriteBinary(IBinaryWriter writer)
+            {
+                throw new BinaryObjectException("Expected");
+            }
+
+            /** <inheritDoc /> */
+            public void ReadBinary(IBinaryReader reader)
+            {
+                throw new BinaryObjectException("Expected");
+            }
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
index 433b635..c693a8b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ResourceTaskTest.cs
@@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Tests.Compute
     using System.Collections.Generic;
     using System.Linq;
     using System.Runtime.Serialization;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Cluster;
     using Apache.Ignite.Core.Compute;
     using Apache.Ignite.Core.Resource;
@@ -158,9 +159,17 @@ namespace Apache.Ignite.Core.Tests.Compute
         /// <summary>
         /// Binarizable job.
         /// </summary>
-        public class InjectionJobBinarizable : InjectionJob
+        public class InjectionJobBinarizable : InjectionJob, IBinarizable
         {
-            // No-op.
+            public void WriteBinary(IBinaryWriter writer)
+            {
+                // No-op.
+            }
+
+            public void ReadBinary(IBinaryReader reader)
+            {
+                // No-op.
+            }
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/79bac4f8/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
index ab5a1a6..ece4894 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DeploymentTest.cs
@@ -15,8 +15,6 @@
  * limitations under the License.
  */
 
-#pragma warning disable 649
-#pragma warning disable 169
 namespace Apache.Ignite.Core.Tests
 {
     using System;
@@ -53,15 +51,21 @@ namespace Apache.Ignite.Core.Tests
             Assert.Greater(jars.Length, 3);
 
             foreach (var jar in jars)
-                // ReSharper disable once AssignNullToNotNullAttribute
-                File.Copy(jar, Path.Combine(folder, Path.GetFileName(jar)), true);
+            {
+                var fileName = Path.GetFileName(jar);
+                Assert.IsNotNull(fileName);
+                File.Copy(jar, Path.Combine(folder, fileName), true);
+            }
 
             // Build classpath
             var classpath = string.Join(";", Directory.GetFiles(folder).Select(Path.GetFileName));
 
             // Copy .NET binaries
-            foreach (var asm in new[] {typeof (IgniteRunner).Assembly, typeof (Ignition).Assembly, GetType().Assembly})
+            foreach (var asm in new[] {typeof(IgniteRunner).Assembly, typeof(Ignition).Assembly, GetType().Assembly})
+            {
+                Assert.IsNotNull(asm.Location);
                 File.Copy(asm.Location, Path.Combine(folder, Path.GetFileName(asm.Location)));
+            }
 
             // Copy config
             var springPath = Path.GetFullPath("config\\compute\\compute-grid2.xml");
@@ -76,7 +80,6 @@ namespace Apache.Ignite.Core.Tests
                 "-springConfigUrl=" + springFile,
                 "-jvmClasspath=" + classpath,
                 "-J-ea",
-                "-J-Xcheck:jni",
                 "-J-Xms512m",
                 "-J-Xmx512m"
             });
@@ -157,6 +160,7 @@ namespace Apache.Ignite.Core.Tests
             throw new InvalidOperationException();
         }
 
+        #pragma warning disable 649
         /// <summary>
         /// Function that returns process path.
         /// </summary>