ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ra...@apache.org
Subject [08/50] [abbrv] ignite git commit: IGNITE-1956: Added binary enums support.
Date Mon, 30 Nov 2015 13:35:12 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
index ea472eb..373e173 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
@@ -80,24 +80,13 @@ namespace Apache.Ignite.Core.Tests.Binary
                         new BinaryTypeConfiguration(typeof (BuilderCollection)),
                         new BinaryTypeConfiguration(typeof (BuilderCollectionItem)),
                         new BinaryTypeConfiguration(typeof (DecimalHolder)),
-                        new BinaryTypeConfiguration(TypeEmpty)
+                        new BinaryTypeConfiguration(TypeEmpty),
+                        new BinaryTypeConfiguration(typeof(TestEnumRegistered))
                     },
                     DefaultIdMapper = new IdMapper()
                 },
                 JvmClasspath = TestUtils.CreateTestClasspath(),
-                JvmOptions = new List<string>
-                {
-                    "-ea",
-                    "-Xcheck:jni",
-                    "-Xms4g",
-                    "-Xmx4g",
-                    "-DIGNITE_QUIET=false",
-                    "-Xnoagent",
-                    "-Djava.compiler=NONE",
-                    "-Xdebug",
-                    "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005",
-                    "-XX:+HeapDumpOnOutOfMemoryError"
-                },
+                JvmOptions = TestUtils.TestJavaOptions(),
                 SpringConfigUrl = "config\\binary.xml"
             };
 
@@ -198,7 +187,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             DateTime date = DateTime.Now.ToUniversalTime();
             Guid guid = Guid.NewGuid();
 
-            IIgniteBinary api = _grid.GetBinary();
+            IBinary api = _grid.GetBinary();
 
             // 1. Primitives.
             Assert.AreEqual(1, api.ToBinary<byte>((byte)1));
@@ -216,7 +205,8 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual("a", api.ToBinary<string>("a"));
             Assert.AreEqual(date, api.ToBinary<DateTime>(date));
             Assert.AreEqual(guid, api.ToBinary<Guid>(guid));
-            Assert.AreEqual(TestEnum.One, api.ToBinary<TestEnum>(TestEnum.One));
+            Assert.AreEqual(TestEnumRegistered.One, api.ToBinary<IBinaryObject>(TestEnumRegistered.One)
+                .Deserialize<TestEnumRegistered>());
 
             // 3. Arrays.
             Assert.AreEqual(new byte[] { 1 }, api.ToBinary<byte[]>(new byte[] { 1 }));
@@ -233,7 +223,9 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { "a" }, api.ToBinary<string[]>(new[] { "a" }));
             Assert.AreEqual(new[] { date }, api.ToBinary<DateTime[]>(new[] { date }));
             Assert.AreEqual(new[] { guid }, api.ToBinary<Guid[]>(new[] { guid }));
-            Assert.AreEqual(new[] { TestEnum.One }, api.ToBinary<TestEnum[]>(new[] { TestEnum.One }));
+            Assert.AreEqual(new[] { TestEnumRegistered.One},
+                api.ToBinary<IBinaryObject[]>(new[] { TestEnumRegistered.One})
+                .Select(x => x.Deserialize<TestEnumRegistered>()).ToArray());
 
             // 4. Objects.
             IBinaryObject binObj = api.ToBinary<IBinaryObject>(new ToBinary(1));
@@ -816,7 +808,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { "str" }, binObj.GetField<string[]>("fStrArr"));
             Assert.AreEqual(new[] { nDate }, binObj.GetField<DateTime?[]>("fDateArr"));
             Assert.AreEqual(new[] { nGuid }, binObj.GetField<Guid?[]>("fGuidArr"));
-            Assert.AreEqual(new[] { TestEnum.One }, binObj.GetField<TestEnum[]>("fEnumArr"));
+            Assert.AreEqual(new[] {TestEnum.One}, binObj.GetField<TestEnum[]>("fEnumArr"));
 
             StringDateGuidEnum obj = binObj.Deserialize<StringDateGuidEnum>();
 
@@ -839,7 +831,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { "str" }, builder.GetField<string[]>("fStrArr"));
             Assert.AreEqual(new[] { nDate }, builder.GetField<DateTime?[]>("fDateArr"));
             Assert.AreEqual(new[] { nGuid }, builder.GetField<Guid?[]>("fGuidArr"));
-            Assert.AreEqual(new[] { TestEnum.One }, builder.GetField<TestEnum[]>("fEnumArr"));
+            Assert.AreEqual(new[] {TestEnum.One}, builder.GetField<TestEnum[]>("fEnumArr"));
 
             // Check reassemble.
             binObj = builder.Build();
@@ -851,7 +843,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { "str" }, binObj.GetField<string[]>("fStrArr"));
             Assert.AreEqual(new[] { nDate }, binObj.GetField<DateTime?[]>("fDateArr"));
             Assert.AreEqual(new[] { nGuid }, binObj.GetField<Guid?[]>("fGuidArr"));
-            Assert.AreEqual(new[] { TestEnum.One }, binObj.GetField<TestEnum[]>("fEnumArr"));
+            Assert.AreEqual(new[] {TestEnum.One}, binObj.GetField<TestEnum[]>("fEnumArr"));
 
             obj = binObj.Deserialize<StringDateGuidEnum>();
 
@@ -889,7 +881,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { "str2" }, binObj.GetField<string[]>("fStrArr"));
             Assert.AreEqual(new[] { nDate }, binObj.GetField<DateTime?[]>("fDateArr"));
             Assert.AreEqual(new[] { nGuid }, binObj.GetField<Guid?[]>("fGuidArr"));
-            Assert.AreEqual(new[] { TestEnum.Two }, binObj.GetField<TestEnum[]>("fEnumArr"));
+            Assert.AreEqual(new[] {TestEnum.Two}, binObj.GetField<TestEnum[]>("fEnumArr"));
 
             obj = binObj.Deserialize<StringDateGuidEnum>();
 
@@ -903,6 +895,24 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { TestEnum.Two }, obj.FEnumArr);
         }
 
+        [Test]
+        public void TestEnumMeta()
+        {
+            var bin = _grid.GetBinary();
+
+            // Put to cache to populate metas
+            var binEnum = bin.ToBinary<IBinaryObject>(TestEnumRegistered.One);
+
+            Assert.AreEqual(_marsh.GetDescriptor(typeof (TestEnumRegistered)).TypeId, binEnum.GetBinaryType().TypeId);
+            Assert.AreEqual(0, binEnum.EnumValue);
+
+            var meta = binEnum.GetBinaryType();
+
+            Assert.IsTrue(meta.IsEnum);
+            Assert.AreEqual(typeof (TestEnumRegistered).Name, meta.TypeName);
+            Assert.AreEqual(0, meta.Fields.Count);
+        }
+
         /// <summary>
         /// Test arrays.
         /// </summary>
@@ -923,7 +933,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(100, binObj.GetHashCode());
 
-            var binInArr = binObj.GetField<object[]>("inArr").Cast<IBinaryObject>().ToArray();
+            var binInArr = binObj.GetField<IBinaryObject[]>("inArr").ToArray();
 
             Assert.AreEqual(1, binInArr.Length);
             Assert.AreEqual(1, binInArr[0].GetField<int>("val"));
@@ -936,11 +946,11 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             // 2. Test addition to array.
             binObj = _grid.GetBinary().GetBuilder(binObj).SetHashCode(200)
-                .SetField("inArr", new object[] { binInArr[0], null }).Build();
+                .SetField("inArr", new[] { binInArr[0], null }).Build();
 
             Assert.AreEqual(200, binObj.GetHashCode());
 
-            binInArr = binObj.GetField<object[]>("inArr").Cast<IBinaryObject>().ToArray();
+            binInArr = binObj.GetField<IBinaryObject[]>("inArr").ToArray();
 
             Assert.AreEqual(2, binInArr.Length);
             Assert.AreEqual(1, binInArr[0].GetField<int>("val"));
@@ -960,7 +970,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(300, binObj.GetHashCode());
 
-            binInArr = binObj.GetField<object[]>("inArr").Cast<IBinaryObject>().ToArray();
+            binInArr = binObj.GetField<IBinaryObject[]>("inArr").ToArray();
 
             Assert.AreEqual(2, binInArr.Length);
             Assert.AreEqual(1, binInArr[0].GetField<int>("val"));
@@ -983,7 +993,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(100, binObj.GetHashCode());
 
-            binInArr = binObj.GetField<object[]>("inArr").Cast<IBinaryObject>().ToArray();
+            binInArr = binObj.GetField<IBinaryObject[]>("inArr").ToArray();
 
             Assert.AreEqual(2, binInArr.Length);
             Assert.AreEqual(1, binInArr[0].GetField<int>("val"));
@@ -1003,7 +1013,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(200, binObj.GetHashCode());
 
-            binInArr = binObj.GetField<object[]>("inArr").Cast<IBinaryObject>().ToArray();
+            binInArr = binObj.GetField<IBinaryObject[]>("inArr").ToArray();
 
             Assert.AreEqual(2, binInArr.Length);
             Assert.AreEqual(2, binInArr[0].GetField<int>("val"));
@@ -1031,7 +1041,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(100, binObj.GetHashCode());
 
-            var binOutArr = binObj.GetField<object[]>("outArr").Cast<IBinaryObject>().ToArray();
+            var binOutArr = binObj.GetField<IBinaryObject[]>("outArr").ToArray();
 
             Assert.AreEqual(2, binOutArr.Length);
             Assert.AreEqual(1, binOutArr[0].GetField<IBinaryObject>("inner").GetField<int>("val"));
@@ -1052,7 +1062,7 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(200, binObj.GetHashCode());
 
-            binInArr = binObj.GetField<object[]>("outArr").Cast<IBinaryObject>().ToArray();
+            binInArr = binObj.GetField<IBinaryObject[]>("outArr").ToArray();
 
             Assert.AreEqual(2, binInArr.Length);
             Assert.AreEqual(2, binOutArr[0].GetField<IBinaryObject>("inner").GetField<int>("val"));
@@ -1387,6 +1397,27 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(new[] {"val", "valArr"}, decimalMeta.Fields);
         }
+
+        [Test]
+        public void TestBuildEnum()
+        {
+            var binary = _grid.GetBinary();
+
+            int val = (int) TestEnumRegistered.Two;
+
+            var binEnums = new[]
+            {
+                binary.BuildEnum(typeof (TestEnumRegistered), val),
+                binary.BuildEnum(typeof (TestEnumRegistered).Name, val)
+            };
+
+            foreach (var binEnum in binEnums)
+            {
+                Assert.IsTrue(binEnum.GetBinaryType().IsEnum);
+                Assert.AreEqual(val, binEnum.EnumValue);
+                Assert.AreEqual((TestEnumRegistered)val, binEnum.Deserialize<TestEnumRegistered>());
+            }
+        }
     }
 
     /// <summary>
@@ -1452,6 +1483,14 @@ namespace Apache.Ignite.Core.Tests.Binary
     }
 
     /// <summary>
+    /// Registered enumeration.
+    /// </summary>
+    public enum TestEnumRegistered
+    {
+        One, Two
+    }
+
+    /// <summary>
     /// binary with raw data.
     /// </summary>
     public class WithRaw : IBinarizable

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
index f7455be..88328ec 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinarySelfTest.cs
@@ -25,6 +25,7 @@ namespace Apache.Ignite.Core.Tests.Binary
     using System;
     using System.Collections;
     using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
     using System.Linq;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Common;
@@ -479,11 +480,18 @@ namespace Apache.Ignite.Core.Tests.Binary
         * <summary>Check write of enum.</summary>
         */
         [Test]
+        [SuppressMessage("ReSharper", "ExpressionIsAlwaysNull")]
         public void TestWriteEnum()
         {
             TestEnum val = TestEnum.Val1;
 
             Assert.AreEqual(_marsh.Unmarshal<TestEnum>(_marsh.Marshal(val)), val);
+
+            TestEnum? val2 = TestEnum.Val1;
+            Assert.AreEqual(_marsh.Unmarshal<TestEnum?>(_marsh.Marshal(val2)), val2);
+
+            val2 = null;
+            Assert.AreEqual(_marsh.Unmarshal<TestEnum?>(_marsh.Marshal(val2)), val2);
         }
 
         /// <summary>
@@ -500,7 +508,13 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             TestEnum val = TestEnum.Val1;
 
-            Assert.AreEqual(marsh.Unmarshal<TestEnum>(marsh.Marshal(val)), val);
+            var data = marsh.Marshal(val);
+
+            Assert.AreEqual(marsh.Unmarshal<TestEnum>(data), val);
+
+            var binEnum = marsh.Unmarshal<IBinaryObject>(data, true);
+
+            Assert.AreEqual(val, (TestEnum) binEnum.EnumValue);
         }
 
         /**
@@ -668,8 +682,13 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             IBinaryObject portNewObj = marsh.Unmarshal<IBinaryObject>(data, BinaryMode.ForceBinary);
 
+            Assert.IsTrue(portNewObj.HasField("field1"));
+            Assert.IsTrue(portNewObj.HasField("field2"));
+            Assert.IsFalse(portNewObj.HasField("field3"));
+
             Assert.AreEqual(obj.Field1, portNewObj.GetField<int>("field1"));
             Assert.AreEqual(obj.Field2, portNewObj.GetField<int>("Field2"));
+            Assert.AreEqual(0, portNewObj.GetField<int>("field3"));
         }
 
         /**
@@ -881,8 +900,11 @@ namespace Apache.Ignite.Core.Tests.Binary
             Marshaller marsh =
                 new Marshaller(new BinaryConfiguration
                 {
-                    TypeConfigurations =
-                        new List<BinaryTypeConfiguration> {new BinaryTypeConfiguration(typeof (EnumType))}
+                    TypeConfigurations = new[]
+                    {
+                        new BinaryTypeConfiguration(typeof (EnumType)),
+                        new BinaryTypeConfiguration(typeof (TestEnum))
+                    }
                 });
 
             EnumType obj = new EnumType
@@ -897,6 +919,19 @@ namespace Apache.Ignite.Core.Tests.Binary
 
             Assert.AreEqual(obj.GetHashCode(), portObj.GetHashCode());
 
+            // Test enum field in binary form
+            var binEnum = portObj.GetField<IBinaryObject>("PEnum");
+            Assert.AreEqual(obj.PEnum.GetHashCode(), binEnum.GetHashCode());
+            Assert.AreEqual((int) obj.PEnum, binEnum.EnumValue);
+            Assert.AreEqual(obj.PEnum, binEnum.Deserialize<TestEnum>());
+            Assert.AreEqual(obj.PEnum, binEnum.Deserialize<object>());
+            Assert.AreEqual(typeof(TestEnum), binEnum.Deserialize<object>().GetType());
+            Assert.AreEqual(null, binEnum.GetField<object>("someField"));
+            Assert.IsFalse(binEnum.HasField("anyField"));
+
+            var binEnumArr = portObj.GetField<IBinaryObject[]>("PEnumArray");
+            Assert.IsTrue(binEnumArr.Select(x => x.Deserialize<TestEnum>()).SequenceEqual(obj.PEnumArray));
+
             EnumType newObj = portObj.Deserialize<EnumType>();
 
             Assert.AreEqual(obj.PEnum, newObj.PEnum);
@@ -1094,7 +1129,7 @@ namespace Apache.Ignite.Core.Tests.Binary
             inner.RawOuter = outer;
 
             var bytes = asbinary
-                ? marsh.Marshal(new IgniteBinary(marsh).ToBinary<IBinaryObject>(outer))
+                ? marsh.Marshal(new Binary(marsh).ToBinary<IBinaryObject>(outer))
                 : marsh.Marshal(outer);
 
             IBinaryObject outerObj;
@@ -2057,6 +2092,11 @@ namespace Apache.Ignite.Core.Tests.Binary
             Val1, Val2, Val3 = 10
         }
 
+        public enum TestEnum2
+        {
+            Val1, Val2, Val3 = 10
+        }
+
         public class DecimalReflective
         {
             /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/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 64124d7..ce15739 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
@@ -347,17 +347,16 @@ namespace Apache.Ignite.Core.Tests.Cache
             for (int i = 0; i < GridCount(); i++)
             {
                 var cache = Cache(i);
+                var entries = cache.Select(pair => pair.ToString() + GetKeyAffinity(cache, pair.Key)).ToArray();
 
-                if (!cache.IsEmpty())
-                {
-                    var entries = Enumerable.Range(0, 2000)
-                        .Select(x => new KeyValuePair<int, int>(x, cache.LocalPeek(x)))
-                        .Where(x => x.Value != 0)
-                        .Select(pair => pair.ToString() + GetKeyAffinity(cache, pair.Key))
-                        .Aggregate((acc, val) => string.Format("{0}, {1}", acc, val));
+                if (entries.Any())
+                    Assert.Fail("Cache '{0}' is not empty in grid [{1}]: ({2})", CacheName(), i,
+                        entries.Aggregate((acc, val) => string.Format("{0}, {1}", acc, val)));
 
-                    Assert.Fail("Cache '{0}' is not empty in grid [{1}]: ({2})", CacheName(), i, entries);
-                }
+                var size = cache.GetSize();
+                Assert.AreEqual(0, size,
+                    "Cache enumerator returned no entries, but cache '{0}' size is {1} in grid [{2}]",
+                    CacheName(), size, i);
             }
 
             Console.WriteLine("Test finished: " + TestContext.CurrentContext.Test.Name);

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/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 1e999e3..87b7f9d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -899,6 +899,12 @@ namespace Apache.Ignite.Core.Tests.Compute
 
             var res = _grid1.GetCompute().ExecuteJavaTask<PlatformComputeEnum>(EchoTask, EchoTypeEnumField);
 
+            var enumMeta = _grid1.GetBinary().GetBinaryType(typeof (PlatformComputeEnum));
+
+            Assert.IsTrue(enumMeta.IsEnum);
+            Assert.AreEqual(enumMeta.TypeName, typeof(PlatformComputeEnum).Name);
+            Assert.AreEqual(0, enumMeta.Fields.Count);
+
             Assert.AreEqual(enumVal, res);
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
index aa58054..3061773 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
@@ -64,7 +64,8 @@
                             <property name="typeName" value="org.apache.ignite.platform.PlatformComputeJavaBinarizable"/>
                         </bean>
                         <bean class="org.apache.ignite.binary.BinaryTypeConfiguration">
-                            <property name="typeName" value="org.apache.ignite.platform.PlatformComputeEnum"/>
+                            <property name="typeName" value="org.apache.ignite.platform.PlatformComputeEnum" />
+                            <property name="enum" value="true" />
                         </bean>
                     </list>
                 </property>

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
index b414a91..25a1d16 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
@@ -41,6 +41,7 @@
                     <property name="atomicityMode" value="TRANSACTIONAL"/>
                     <property name="writeThrough" value="true"/>
                     <property name="readThrough" value="true"/>
+                    <property name="keepBinaryInStore" value="true"/>
 
                     <property name="cacheStoreFactory">
                         <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory">

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs
index 1797337..973381c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs
@@ -48,7 +48,7 @@ namespace Apache.Ignite.Core.Tests.Services
         });
 
         /** */
-        protected readonly IIgniteBinary IgniteBinary;
+        protected readonly IBinary Binary;
 
         /** */
         private readonly PlatformMemoryManager _memory = new PlatformMemoryManager(1024);
@@ -64,7 +64,7 @@ namespace Apache.Ignite.Core.Tests.Services
         /// </summary>
         public ServiceProxyTest()
         {
-            IgniteBinary = new IgniteBinary(_marsh);
+            Binary = new Binary(_marsh);
         }
 
         /// <summary>
@@ -243,7 +243,7 @@ namespace Apache.Ignite.Core.Tests.Services
         /// </summary>
         protected T GetProxy<T>()
         {
-            _svc = new TestIgniteService(IgniteBinary);
+            _svc = new TestIgniteService(Binary);
 
             var prx = new ServiceProxy<T>(InvokeProxyMethod).GetTransparentProxy();
 
@@ -439,15 +439,15 @@ namespace Apache.Ignite.Core.Tests.Services
         private class TestIgniteService : ITestIgniteService, ITestIgniteServiceAmbiguity
         {
             /** */
-            private readonly IIgniteBinary _igniteBinary;
+            private readonly IBinary _binary;
 
             /// <summary>
             /// Initializes a new instance of the <see cref="TestIgniteService"/> class.
             /// </summary>
-            /// <param name="igniteBinary">Binary.</param>
-            public TestIgniteService(IIgniteBinary igniteBinary)
+            /// <param name="binary">Binary.</param>
+            public TestIgniteService(IBinary binary)
             {
-                _igniteBinary = igniteBinary;
+                _binary = binary;
             }
 
             /** <inheritdoc /> */
@@ -534,13 +534,13 @@ namespace Apache.Ignite.Core.Tests.Services
             /** <inheritdoc /> */
             public IBinaryObject BinarizableResultMethod(int arg1, TestBinarizableClass arg2)
             {
-                return _igniteBinary.ToBinary<IBinaryObject>(arg2);
+                return _binary.ToBinary<IBinaryObject>(arg2);
             }
 
             /** <inheritdoc /> */
             public IBinaryObject BinarizableArgAndResultMethod(int arg1, IBinaryObject arg2)
             {
-                return _igniteBinary.ToBinary<IBinaryObject>(arg2.Deserialize<TestBinarizableClass>());
+                return _binary.ToBinary<IBinaryObject>(arg2.Deserialize<TestBinarizableClass>());
             }
 
             /** <inheritdoc /> */
@@ -703,7 +703,7 @@ namespace Apache.Ignite.Core.Tests.Services
             var prx = GetProxy();
 
             var obj = new TestBinarizableClass { Prop = "PropValue" };
-            var portObj = IgniteBinary.ToBinary<IBinaryObject>(obj);
+            var portObj = Binary.ToBinary<IBinaryObject>(obj);
 
             var result = prx.BinarizableArgMethod(1, portObj);
 
@@ -731,7 +731,7 @@ namespace Apache.Ignite.Core.Tests.Services
             var prx = GetProxy();
             
             var obj = new TestBinarizableClass { Prop = "PropValue" };
-            var portObj = IgniteBinary.ToBinary<IBinaryObject>(obj);
+            var portObj = Binary.ToBinary<IBinaryObject>(obj);
 
             var result = prx.BinarizableArgAndResultMethod(1, portObj);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index ae10159..2c7d787 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -134,6 +134,7 @@
     <Compile Include="IgniteConfiguration.cs" />
     <Compile Include="Ignition.cs" />
     <Compile Include="IIgnite.cs" />
+    <Compile Include="Impl\Binary\BinaryEnum.cs" />
     <Compile Include="Impl\Cache\CacheAffinityImpl.cs" />
     <Compile Include="Impl\Cache\CacheEntry.cs" />
     <Compile Include="Impl\Cache\CacheEntryFilterHolder.cs" />
@@ -266,7 +267,7 @@
     <Compile Include="Impl\Binary\BinaryReader.cs" />
     <Compile Include="Impl\Binary\BinaryReflectiveActions.cs" />
     <Compile Include="Impl\Binary\BinaryReflectiveSerializer.cs" />
-    <Compile Include="Impl\Binary\IgniteBinary.cs" />
+    <Compile Include="Impl\Binary\Binary.cs" />
     <Compile Include="Impl\Binary\Structure\BinaryStructureTracker.cs" />
     <Compile Include="Impl\Binary\BinarySurrogateTypeDescriptor.cs" />
     <Compile Include="Impl\Binary\BinarySystemHandlers.cs" />
@@ -316,7 +317,7 @@
     <Compile Include="Binary\IBinaryRawReader.cs" />
     <Compile Include="Binary\IBinaryRawWriter.cs" />
     <Compile Include="Binary\IBinaryReader.cs" />
-    <Compile Include="Binary\IIgniteBinary.cs" />
+    <Compile Include="Binary\IBinary.cs" />
     <Compile Include="Binary\IBinarySerializer.cs" />
     <Compile Include="Binary\IBinaryWriter.cs" />
     <Compile Include="Binary\BinaryConfiguration.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
index 967aa52..99f8572 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
@@ -48,6 +48,7 @@ namespace Apache.Ignite.Core.Binary
         public BinaryTypeConfiguration(Type type)
         {
             TypeName = type.AssemblyQualifiedName;
+            IsEnum = type.IsEnum;
         }
 
         /// <summary>
@@ -62,6 +63,7 @@ namespace Apache.Ignite.Core.Binary
             Serializer = cfg.Serializer;
             TypeName = cfg.TypeName;
             KeepDeserialized = cfg.KeepDeserialized;
+            IsEnum = cfg.IsEnum;
         }
 
         /// <summary>
@@ -101,6 +103,11 @@ namespace Apache.Ignite.Core.Binary
         public bool? KeepDeserialized { get; set; }
 
         /// <summary>
+        /// Gets or sets a value indicating whether this instance describes an enum type.
+        /// </summary>
+        public bool IsEnum { get; set; }
+
+        /// <summary>
         /// Returns a string that represents the current object.
         /// </summary>
         /// <returns>
@@ -108,9 +115,12 @@ namespace Apache.Ignite.Core.Binary
         /// </returns>
         public override string ToString()
         {
-            return typeof (BinaryTypeConfiguration).Name + " [TypeName=" + TypeName +
-                   ", NameMapper=" + NameMapper + ", IdMapper=" + IdMapper + ", Serializer=" + Serializer +
-                   ", AffinityKeyFieldName=" + AffinityKeyFieldName + ']';
+            return
+                string.Format(
+                    "{0} [TypeName={1}, NameMapper={2}, IdMapper={3}, Serializer={4}, AffinityKeyFieldName={5}, " +
+                    "KeepDeserialized={6}, IsEnum={7}]",
+                    typeof (BinaryTypeConfiguration).Name, TypeName, NameMapper, IdMapper, Serializer,
+                    AffinityKeyFieldName, KeepDeserialized, IsEnum);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
new file mode 100644
index 0000000..a0fc17f
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
@@ -0,0 +1,136 @@
+/*
+ * 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.Binary
+{
+    using System;
+    using System.Collections.Generic;
+
+    /// <summary>
+    /// Defines binary objects functionality. With binary objects you are able to:
+    /// <list type="bullet">
+    ///     <item>
+    ///         <description>Seamlessly interoperate between Java, .NET, and C++.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Make any object binary with zero code change to your existing code.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Nest binary objects within each other.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Automatically handle <c>circular</c> or <c>null</c> references.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Automatically convert collections and maps between Java, .NET, and C++.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Optionally avoid deserialization of objects on the server side.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Avoid need to have concrete class definitions on the server side.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Dynamically change structure of the classes without having to restart the cluster.</description>
+    ///     </item>
+    ///     <item>
+    ///         <description>Index into binary objects for querying purposes.</description>
+    ///     </item>
+    /// </list>
+    /// </summary>
+    public interface IBinary
+    {
+        /// <summary>
+        /// Converts provided object to binary form.
+        /// <para />
+        /// Note that object's type needs to be configured in <see cref="BinaryConfiguration"/>.
+        /// </summary>
+        /// <param name="obj">Object to convert.</param>
+        /// <returns>Converted object.</returns>
+        T ToBinary<T>(object obj);
+
+        /// <summary>
+        /// Create builder for the given binary object type. Note that this
+        /// type must be specified in <see cref="BinaryConfiguration"/>.
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns>Builder.</returns>
+        IBinaryObjectBuilder GetBuilder(Type type);
+
+        /// <summary>
+        /// Create builder for the given binary object type name. Note that this
+        /// type name must be specified in <see cref="BinaryConfiguration"/>.
+        /// </summary>
+        /// <param name="typeName">Type name.</param>
+        /// <returns>Builder.</returns>
+        IBinaryObjectBuilder GetBuilder(string typeName);
+
+        /// <summary>
+        /// Create builder over existing binary object.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns>Builder.</returns>
+        IBinaryObjectBuilder GetBuilder(IBinaryObject obj);
+
+        /// <summary>
+        /// Gets type id for the given type name.
+        /// </summary>
+        /// <param name="typeName">Type name.</param>
+        /// <returns>Type id.</returns>
+        int GetTypeId(string typeName);
+
+        /// <summary>
+        /// Gets metadata for all known types.
+        /// </summary>
+        /// <returns>Metadata.</returns>
+        ICollection<IBinaryType> GetBinaryTypes();
+
+        /// <summary>
+        /// Gets metadata for specified type id.
+        /// </summary>
+        /// <returns>Metadata.</returns>
+        IBinaryType GetBinaryType(int typeId);
+
+        /// <summary>
+        /// Gets metadata for specified type name.
+        /// </summary>
+        /// <returns>Metadata.</returns>
+        IBinaryType GetBinaryType(string typeName);
+
+        /// <summary>
+        /// Gets metadata for specified type.
+        /// </summary>
+        /// <returns>Metadata.</returns>
+        IBinaryType GetBinaryType(Type type);
+
+        /// <summary>
+        /// Converts enum to a binary form.
+        /// </summary>
+        /// <param name="typeName">Enum type name.</param>
+        /// <param name="value">Enum int value.</param>
+        /// <returns>Binary representation of the specified enum value.</returns>
+        IBinaryObject BuildEnum(string typeName, int value);
+
+        /// <summary>
+        /// Converts enum to a binary form.
+        /// </summary>
+        /// <param name="type">Enum type.</param>
+        /// <param name="value">Enum int value.</param>
+        /// <returns>Binary representation of the specified enum value.</returns>
+        IBinaryObject BuildEnum(Type type, int value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
index bd60e28..c5aa80e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
@@ -25,14 +25,6 @@ namespace Apache.Ignite.Core.Binary
     public interface IBinaryObject
     {
         /// <summary>
-        /// Gets binary object type ID.
-        /// </summary>
-        /// <value>
-        /// Type ID.
-        /// </value>
-        int TypeId { get; }
-
-        /// <summary>
         /// Gets object metadata.
         /// </summary>
         /// <returns>Metadata.</returns>
@@ -50,11 +42,26 @@ namespace Apache.Ignite.Core.Binary
         TF GetField<TF>(string fieldName);
 
         /// <summary>
+        /// Determines whether the field with specified name exists in this instance.
+        /// </summary>
+        /// <param name="fieldName">Name of the field.</param>
+        /// <returns>True if there is a field with specified name; false otherwise.</returns>
+        bool HasField(string fieldName);
+
+        /// <summary>
         /// Gets fully deserialized instance of binary object.
         /// </summary>
         /// <returns>
         /// Fully deserialized instance of binary object.
         /// </returns>
         T Deserialize<T>();
+
+        /// <summary>
+        /// Gets the value of underlying enum in int form.
+        /// </summary>
+        /// <value>
+        /// The value of underlying enum in int form.
+        /// </value>
+        int EnumValue { get; }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
index 7b34e07..bec863f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
@@ -48,5 +48,18 @@ namespace Apache.Ignite.Core.Binary
         /// </summary>
         /// <returns>Affinity key field name or null in case it is not provided.</returns>
         string AffinityKeyFieldName { get; }
+
+        /// <summary>
+        /// Gets a value indicating whether this type represents an enum.
+        /// </summary>
+        /// <value>   
+        /// <c>true</c> if this instance represents an enum; otherwise, <c>false</c>.
+        /// </value>
+        bool IsEnum { get; }
+
+        /// <summary>
+        /// Gets the type identifier.
+        /// </summary>
+        int TypeId { get; }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IIgniteBinary.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IIgniteBinary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IIgniteBinary.cs
deleted file mode 100644
index 25ea981..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IIgniteBinary.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Apache.Ignite.Core.Binary
-{
-    using System;
-    using System.Collections.Generic;
-
-    /// <summary>
-    /// Defines binary objects functionality. With binary objects you are able to:
-    /// <list type="bullet">
-    ///     <item>
-    ///         <description>Seamlessly interoperate between Java, .NET, and C++.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Make any object binary with zero code change to your existing code.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Nest binary objects within each other.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Automatically handle <c>circular</c> or <c>null</c> references.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Automatically convert collections and maps between Java, .NET, and C++.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Optionally avoid deserialization of objects on the server side.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Avoid need to have concrete class definitions on the server side.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Dynamically change structure of the classes without having to restart the cluster.</description>
-    ///     </item>
-    ///     <item>
-    ///         <description>Index into binary objects for querying purposes.</description>
-    ///     </item>
-    /// </list>
-    /// </summary>
-    public interface IIgniteBinary
-    {
-        /// <summary>
-        /// Converts provided object to binary form.
-        /// <para />
-        /// Note that object's type needs to be configured in <see cref="BinaryConfiguration"/>.
-        /// </summary>
-        /// <param name="obj">Object to convert.</param>
-        /// <returns>Converted object.</returns>
-        T ToBinary<T>(object obj);
-
-        /// <summary>
-        /// Create builder for the given binary object type. Note that this
-        /// type must be specified in <see cref="BinaryConfiguration"/>.
-        /// </summary>
-        /// <param name="type"></param>
-        /// <returns>Builder.</returns>
-        IBinaryObjectBuilder GetBuilder(Type type);
-
-        /// <summary>
-        /// Create builder for the given binary object type name. Note that this
-        /// type name must be specified in <see cref="BinaryConfiguration"/>.
-        /// </summary>
-        /// <param name="typeName">Type name.</param>
-        /// <returns>Builder.</returns>
-        IBinaryObjectBuilder GetBuilder(string typeName);
-
-        /// <summary>
-        /// Create builder over existing binary object.
-        /// </summary>
-        /// <param name="obj"></param>
-        /// <returns>Builder.</returns>
-        IBinaryObjectBuilder GetBuilder(IBinaryObject obj);
-
-        /// <summary>
-        /// Gets type id for the given type name.
-        /// </summary>
-        /// <param name="typeName">Type name.</param>
-        /// <returns>Type id.</returns>
-        int GetTypeId(string typeName);
-
-        /// <summary>
-        /// Gets metadata for all known types.
-        /// </summary>
-        /// <returns>Metadata.</returns>
-        ICollection<IBinaryType> GetBinaryTypes();
-
-        /// <summary>
-        /// Gets metadata for specified type id.
-        /// </summary>
-        /// <returns>Metadata.</returns>
-        IBinaryType GetBinaryType(int typeId);
-
-        /// <summary>
-        /// Gets metadata for specified type name.
-        /// </summary>
-        /// <returns>Metadata.</returns>
-        IBinaryType GetBinaryType(string typeName);
-
-        /// <summary>
-        /// Gets metadata for specified type.
-        /// </summary>
-        /// <returns>Metadata.</returns>
-        IBinaryType GetBinaryType(Type type);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
index b9d9555..08e5f6b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
@@ -111,11 +111,11 @@ namespace Apache.Ignite.Core
         IDataStreamer<TK, TV> GetDataStreamer<TK, TV>(string cacheName);
 
         /// <summary>
-        /// Gets an instance of <see cref="IIgniteBinary"/> interface.
+        /// Gets an instance of <see cref="IBinary"/> interface.
         /// </summary>
-        /// <returns>Instance of <see cref="IIgniteBinary"/> interface</returns>
+        /// <returns>Instance of <see cref="IBinary"/> interface</returns>
         [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Semantics.")]
-        IIgniteBinary GetBinary();
+        IBinary GetBinary();
 
         /// <summary>
         /// Gets affinity service to provide information about data partitioning and distribution.

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
new file mode 100644
index 0000000..43a4bb8
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+    using System.Collections.Generic;
+    using System.IO;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl.Binary.IO;
+    using Apache.Ignite.Core.Impl.Binary.Metadata;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Binary implementation.
+    /// </summary>
+    internal class Binary : IBinary
+    {
+        /** Owning grid. */
+        private readonly Marshaller _marsh;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="marsh">Marshaller.</param>
+        internal Binary(Marshaller marsh)
+        {
+            _marsh = marsh;
+        }
+
+        /** <inheritDoc /> */
+        public T ToBinary<T>(object obj)
+        {
+            if (obj is IBinaryObject)
+                return (T)obj;
+
+            IBinaryStream stream = new BinaryHeapStream(1024);
+
+            // Serialize.
+            BinaryWriter writer = _marsh.StartMarshal(stream);
+
+            try
+            {
+                writer.Write(obj);
+            }
+            finally
+            {
+                // Save metadata.
+                _marsh.FinishMarshal(writer);
+            }
+
+            // Deserialize.
+            stream.Seek(0, SeekOrigin.Begin);
+
+            return _marsh.Unmarshal<T>(stream, BinaryMode.ForceBinary);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObjectBuilder GetBuilder(Type type)
+        {
+            IgniteArgumentCheck.NotNull(type, "type");
+
+            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(type);
+
+            if (desc == null)
+                throw new IgniteException("Type is not binary (add it to BinaryConfiguration): " + 
+                    type.FullName);
+
+            return Builder0(null, BinaryFromDescriptor(desc), desc);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObjectBuilder GetBuilder(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(typeName);
+            
+            return Builder0(null, BinaryFromDescriptor(desc), desc);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObjectBuilder GetBuilder(IBinaryObject obj)
+        {
+            IgniteArgumentCheck.NotNull(obj, "obj");
+
+            BinaryObject obj0 = obj as BinaryObject;
+
+            if (obj0 == null)
+                throw new ArgumentException("Unsupported object type: " + obj.GetType());
+
+            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(true, obj0.TypeId);
+            
+            return Builder0(null, obj0, desc);
+        }
+
+        /** <inheritDoc /> */
+        public int GetTypeId(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            return Marshaller.GetDescriptor(typeName).TypeId;
+        }
+
+        /** <inheritDoc /> */
+        public ICollection<IBinaryType> GetBinaryTypes()
+        {
+            return Marshaller.Ignite.ClusterGroup.GetBinaryTypes();
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryType GetBinaryType(int typeId)
+        {
+            return Marshaller.GetBinaryType(typeId);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryType GetBinaryType(string typeName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            return GetBinaryType(GetTypeId(typeName));
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryType GetBinaryType(Type type)
+        {
+            IgniteArgumentCheck.NotNull(type, "type");
+
+            var desc = Marshaller.GetDescriptor(type);
+
+            return desc == null ? null : Marshaller.GetBinaryType(desc.TypeId);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObject BuildEnum(string typeName, int value)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            var desc = Marshaller.GetDescriptor(typeName);
+
+            IgniteArgumentCheck.Ensure(desc.IsEnum, "typeName", "Type should be an Enum.");
+
+            _marsh.PutBinaryType(desc);
+
+            return new BinaryEnum(GetTypeId(typeName), value, Marshaller);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObject BuildEnum(Type type, int value)
+        {
+            IgniteArgumentCheck.NotNull(type, "type");
+            IgniteArgumentCheck.Ensure(type.IsEnum, "type", "Type should be an Enum.");
+
+            return BuildEnum(type.Name, value);
+        }
+
+        /// <summary>
+        /// Marshaller.
+        /// </summary>
+        internal Marshaller Marshaller
+        {
+            get
+            {
+                return _marsh;
+            }
+        }
+
+        /// <summary>
+        /// Create empty binary object from descriptor.
+        /// </summary>
+        /// <param name="desc">Descriptor.</param>
+        /// <returns>Empty binary object.</returns>
+        private BinaryObject BinaryFromDescriptor(IBinaryTypeDescriptor desc)
+        {
+            var len = BinaryObjectHeader.Size;
+
+            var hdr = new BinaryObjectHeader(desc.TypeId, 0, len, 0, len,
+                desc.UserType ? BinaryObjectHeader.Flag.UserType : BinaryObjectHeader.Flag.None);
+
+            var stream = new BinaryHeapStream(len);
+
+            BinaryObjectHeader.Write(hdr, stream, 0);
+
+            return new BinaryObject(_marsh, stream.InternalArray, 0, hdr);
+        }
+
+        /// <summary>
+        /// Internal builder creation routine.
+        /// </summary>
+        /// <param name="parent">Parent builder.</param>
+        /// <param name="obj">binary object.</param>
+        /// <param name="desc">Type descriptor.</param>
+        /// <returns>Builder.</returns>
+        private BinaryObjectBuilder Builder0(BinaryObjectBuilder parent, BinaryObject obj, 
+            IBinaryTypeDescriptor desc)
+        {
+            return new BinaryObjectBuilder(this, parent, obj, desc);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
new file mode 100644
index 0000000..97f44b0
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Binary
+{
+    using System;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Binary;
+
+    /// <summary>
+    /// Represents a typed enum in binary form.
+    /// </summary>
+    internal class BinaryEnum : IBinaryObject, IEquatable<BinaryEnum>
+    {
+        /** Type id. */
+        private readonly int _typeId;
+
+        /** Value. */
+        private readonly int _enumValue;
+
+        /** Marshaller. */
+        private readonly Marshaller _marsh;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BinaryEnum" /> class.
+        /// </summary>
+        /// <param name="typeId">The type identifier.</param>
+        /// <param name="enumValue">The value.</param>
+        /// <param name="marsh">The marshaller.</param>
+        public BinaryEnum(int typeId, int enumValue, Marshaller marsh)
+        {
+            Debug.Assert(marsh != null);
+
+            _typeId = typeId;
+            _enumValue = enumValue;
+            _marsh = marsh;
+        }
+
+        /** <inheritdoc /> */
+        public int TypeId
+        {
+            get { return _typeId; }
+        }
+
+        /** <inheritdoc /> */
+        public IBinaryType GetBinaryType()
+        {
+            return _marsh.GetBinaryType(_typeId);
+        }
+
+        /** <inheritdoc /> */
+        public TF GetField<TF>(string fieldName)
+        {
+            return default(TF);
+        }
+
+        /** <inheritdoc /> */
+        public bool HasField(string fieldName)
+        {
+            return false;
+        }
+
+        /** <inheritdoc /> */
+        public T Deserialize<T>()
+        {
+            return BinaryUtils.GetEnumValue<T>(_enumValue, _typeId, _marsh);
+        }
+
+        /** <inheritdoc /> */
+        public int EnumValue
+        {
+            get { return _enumValue; }
+        }
+
+        /** <inheritdoc /> */
+        public bool Equals(BinaryEnum other)
+        {
+            if (ReferenceEquals(null, other))
+                return false;
+
+            if (ReferenceEquals(this, other))
+                return true;
+
+            return _typeId == other._typeId && _enumValue == other._enumValue;
+        }
+
+        /** <inheritdoc /> */
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj))
+                return false;
+
+            if (ReferenceEquals(this, obj))
+                return true;
+
+            if (obj.GetType() != GetType())
+                return false;
+
+            return Equals((BinaryEnum) obj);
+        }
+
+        /** <inheritdoc /> */
+        public override int GetHashCode()
+        {
+            return _enumValue.GetHashCode();
+        }
+
+        /** <inheritdoc /> */
+        public static bool operator ==(BinaryEnum left, BinaryEnum right)
+        {
+            return Equals(left, right);
+        }
+
+        /** <inheritdoc /> */
+        public static bool operator !=(BinaryEnum left, BinaryEnum right)
+        {
+            return !Equals(left, right);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
index 9649595..3d2b34d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryFullTypeDescriptor.cs
@@ -63,6 +63,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** Type schema. */
         private readonly BinaryObjectSchema _schema = new BinaryObjectSchema();
 
+        /** Enum flag. */
+        private bool _isEnum;
+
         /// <summary>
         /// Constructor.
         /// </summary>
@@ -75,6 +78,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="serializer">Serializer.</param>
         /// <param name="keepDeserialized">Whether to cache deserialized value in IBinaryObject</param>
         /// <param name="affKeyFieldName">Affinity field key name.</param>
+        /// <param name="isEnum">Enum flag.</param>
         public BinaryFullTypeDescriptor(
             Type type, 
             int typeId, 
@@ -84,7 +88,8 @@ namespace Apache.Ignite.Core.Impl.Binary
             IBinaryIdMapper idMapper, 
             IBinarySerializer serializer, 
             bool keepDeserialized, 
-            string affKeyFieldName)
+            string affKeyFieldName,
+            bool isEnum)
         {
             _type = type;
             _typeId = typeId;
@@ -95,6 +100,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             _serializer = serializer;
             _keepDeserialized = keepDeserialized;
             _affKeyFieldName = affKeyFieldName;
+            _isEnum = isEnum;
         }
 
         /// <summary>
@@ -169,6 +175,12 @@ namespace Apache.Ignite.Core.Impl.Binary
             get { return _affKeyFieldName; }
         }
 
+        /** <inheritdoc/> */
+        public bool IsEnum
+        {
+            get { return _isEnum; }
+        }
+
         /** <inheritDoc /> */
         public BinaryStructure WriterTypeStructure
         {

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
index fd60da7..90607dd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
@@ -17,14 +17,17 @@
 
 namespace Apache.Ignite.Core.Impl.Binary
 {
+    using System;
     using System.Collections;
     using System.Collections.Generic;
+    using System.Diagnostics;
     using System.IO;
     using System.Runtime.CompilerServices;
     using System.Text;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Impl.Binary.IO;
+    using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
     /// Binary object.
@@ -61,6 +64,10 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="header">The header.</param>
         public BinaryObject(Marshaller marsh, byte[] data, int offset, BinaryObjectHeader header)
         {
+            Debug.Assert(marsh != null);
+            Debug.Assert(data != null);
+            Debug.Assert(offset >= 0 && offset < data.Length);
+
             _marsh = marsh;
 
             _data = data;
@@ -78,11 +85,23 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** <inheritdoc /> */
         public T GetField<T>(string fieldName)
         {
+            IgniteArgumentCheck.NotNullOrEmpty(fieldName, "fieldName");
+
             int pos;
 
             return TryGetFieldPosition(fieldName, out pos) ? GetField<T>(pos, null) : default(T);
         }
 
+        /** <inheritdoc /> */
+        public bool HasField(string fieldName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(fieldName, "fieldName");
+
+            int pos;
+
+            return TryGetFieldPosition(fieldName, out pos);
+        }
+
         /// <summary>
         /// Gets field value on the given object.
         /// </summary>
@@ -104,6 +123,16 @@ namespace Apache.Ignite.Core.Impl.Binary
             return Deserialize<T>(BinaryMode.Deserialize);
         }
 
+        /** <inheritdoc /> */
+        public int EnumValue
+        {
+            get
+            {
+                throw new NotSupportedException("IBinaryObject.Value is only supported for enums. " +
+                    "Check IBinaryObject.IsEnum property before accessing Value.");
+            }
+        }
+
         /// <summary>
         /// Internal deserialization routine.
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
index 97cc381..7ef6259 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
@@ -37,7 +37,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             new Dictionary<int, BinaryBuilderField>();
         
         /** Binary. */
-        private readonly IgniteBinary _igniteBinary;
+        private readonly Binary _binary;
 
         /** */
         private readonly BinaryObjectBuilder _parent;
@@ -79,18 +79,18 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Constructor.
         /// </summary>
-        /// <param name="igniteBinary">Binary.</param>
+        /// <param name="binary">Binary.</param>
         /// <param name="parent">Parent builder.</param>
         /// <param name="obj">Initial binary object.</param>
         /// <param name="desc">Type descriptor.</param>
-        public BinaryObjectBuilder(IgniteBinary igniteBinary, BinaryObjectBuilder parent, 
+        public BinaryObjectBuilder(Binary binary, BinaryObjectBuilder parent, 
             BinaryObject obj, IBinaryTypeDescriptor desc)
         {
-            Debug.Assert(igniteBinary != null);
+            Debug.Assert(binary != null);
             Debug.Assert(obj != null);
             Debug.Assert(desc != null);
 
-            _igniteBinary = igniteBinary;
+            _binary = binary;
             _parent = parent ?? this;
             _obj = obj;
             _desc = desc;
@@ -361,7 +361,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             BinaryHeapStream outStream = new BinaryHeapStream(estimatedCapacity);
 
-            BinaryWriter writer = _igniteBinary.Marshaller.StartMarshal(outStream);
+            BinaryWriter writer = _binary.Marshaller.StartMarshal(outStream);
 
             writer.SetBuilder(this);
 
@@ -374,10 +374,10 @@ namespace Apache.Ignite.Core.Impl.Binary
                 writer.Write(this);
                 
                 // Process metadata.
-                _igniteBinary.Marshaller.FinishMarshal(writer);
+                _binary.Marshaller.FinishMarshal(writer);
 
                 // Create binary object once metadata is processed.
-                return new BinaryObject(_igniteBinary.Marshaller, outStream.InternalArray, 0, 
+                return new BinaryObject(_binary.Marshaller, outStream.InternalArray, 0, 
                     BinaryObjectHeader.Read(outStream, 0));
             }
             finally
@@ -394,9 +394,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <returns>Child builder.</returns>
         public BinaryObjectBuilder Child(BinaryObject obj)
         {
-            var desc = _igniteBinary.Marshaller.GetDescriptor(true, obj.TypeId);
+            var desc = _binary.Marshaller.GetDescriptor(true, obj.TypeId);
 
-            return new BinaryObjectBuilder(_igniteBinary, null, obj, desc);
+            return new BinaryObjectBuilder(_binary, null, obj, desc);
         }
         
         /// <summary>
@@ -436,7 +436,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             var hdr = _obj.Data[pos];
 
-            var field = new BinaryBuilderField(typeof(T), val, hdr, GetWriteAction(hdr));
+            var field = new BinaryBuilderField(typeof(T), val, hdr, GetWriteAction(hdr, pos));
             
             _parent._cache[pos] = field;
 
@@ -447,8 +447,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// Gets the write action by header.
         /// </summary>
         /// <param name="header">The header.</param>
+        /// <param name="pos">Position.</param>
         /// <returns>Write action.</returns>
-        private static Action<BinaryWriter, object> GetWriteAction(byte header)
+        private Action<BinaryWriter, object> GetWriteAction(byte header, int pos)
         {
             // We need special actions for all cases where SetField(X) produces different result from SetSpecialField(X)
             // Arrays, Collections, Dates
@@ -466,9 +467,20 @@ namespace Apache.Ignite.Core.Impl.Binary
 
                 case BinaryUtils.TypeArrayTimestamp:
                     return WriteTimestampArrayAction;
-            }
 
-            return null;
+                case BinaryUtils.TypeArrayEnum:
+                    using (var stream = new BinaryHeapStream(_obj.Data))
+                    {
+                        stream.Seek(pos, SeekOrigin.Begin + 1);
+
+                        var elementTypeId = stream.ReadInt();
+
+                        return (w, o) => w.WriteEnumArrayInternal((Array) o, elementTypeId);
+                    }
+
+                default:
+                    return null;
+            }
         }
 
         /// <summary>
@@ -510,7 +522,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             try
             {
                 // Prepare fields.
-                IBinaryTypeHandler metaHnd = _igniteBinary.Marshaller.GetBinaryTypeHandler(desc);
+                IBinaryTypeHandler metaHnd = _binary.Marshaller.GetBinaryTypeHandler(desc);
 
                 IDictionary<int, BinaryBuilderField> vals0;
 
@@ -546,7 +558,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                     IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished();
 
                     if (meta != null)
-                        _parent._ctx.Writer.SaveMetadata(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
+                        _parent._ctx.Writer.SaveMetadata(desc, meta);
                 }
             }
             finally

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
index 9aeb908..7b887a9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
@@ -399,13 +399,34 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** <inheritdoc /> */
         public T ReadEnum<T>(string fieldName)
         {
-            return ReadField(fieldName, BinaryUtils.ReadEnum<T>, BinaryUtils.TypeEnum);
+            return SeekField(fieldName) ? ReadEnum<T>() : default(T);
         }
 
         /** <inheritdoc /> */
         public T ReadEnum<T>()
         {
-            return Read(BinaryUtils.ReadEnum<T>, BinaryUtils.TypeEnum);
+            var hdr = ReadByte();
+
+            switch (hdr)
+            {
+                case BinaryUtils.HdrNull:
+                    return default(T);
+
+                case BinaryUtils.TypeEnum:
+                    // Never read enums in binary mode when reading a field (we do not support half-binary objects)
+                    return ReadEnum0<T>(this, false);  
+
+                case BinaryUtils.HdrFull:
+                    // Unregistered enum written as serializable
+                    Stream.Seek(-1, SeekOrigin.Current);
+
+                    return ReadObject<T>(); 
+
+                default:
+                    throw new BinaryObjectException(
+                        string.Format("Invalid header on enum deserialization. Expected: {0} or {1} but was: {2}",
+                            BinaryUtils.TypeEnum, BinaryUtils.HdrFull, hdr));
+            }
         }
 
         /** <inheritdoc /> */
@@ -560,15 +581,16 @@ namespace Apache.Ignite.Core.Impl.Binary
                     res = ReadBinaryObject<T>(doDetach);
 
                     return true;
-            }
 
-            if (BinaryUtils.IsPredefinedType(hdr))
-            {
-                res = BinarySystemHandlers.ReadSystemType<T>(hdr, this);
+                case BinaryUtils.TypeEnum:
+                    res = ReadEnum0<T>(this, _mode != BinaryMode.Deserialize);
 
-                return true;
+                    return true;
             }
 
+            if (BinarySystemHandlers.TryReadSystemType(hdr, this, out res))
+                return true;
+
             throw new BinaryObjectException("Invalid header on deserialization [pos=" + pos + ", hdr=" + hdr + ']');
         }
 
@@ -961,5 +983,20 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             return IsNotNullHeader(expHdr) ? readFunc(Stream) : default(T);
         }
+
+        /// <summary>
+        /// Reads the enum.
+        /// </summary>
+        private static T ReadEnum0<T>(BinaryReader reader, bool keepBinary)
+        {
+            var enumType = reader.ReadInt();
+
+            var enumValue = reader.ReadInt();
+
+            if (!keepBinary)
+                return BinaryUtils.GetEnumValue<T>(enumValue, enumType, reader.Marshaller);
+
+            return TypeCaster<T>.Cast(new BinaryEnum(enumType, enumValue, reader.Marshaller));
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
index 247b40d..04028b5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySurrogateTypeDescriptor.cs
@@ -124,6 +124,12 @@ namespace Apache.Ignite.Core.Impl.Binary
             get { return null; }
         }
 
+        /** <inheritdoc/> */
+        public bool IsEnum
+        {
+            get { return false; }
+        }
+
         /** <inheritDoc /> */
         public BinaryStructure WriterTypeStructure
         {

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
index b49c29d..0af1e82 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
@@ -22,6 +22,7 @@ namespace Apache.Ignite.Core.Impl.Binary
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
+    using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
     using Apache.Ignite.Core.Impl.Common;
 
@@ -166,7 +167,6 @@ namespace Apache.Ignite.Core.Impl.Binary
             ReadHandlers[BinaryUtils.TypeMapEntry] = new BinarySystemReader(ReadMapEntry);
             
             // 16. Enum.
-            ReadHandlers[BinaryUtils.TypeEnum] = new BinarySystemReader<int>(BinaryUtils.ReadEnum<int>);
             ReadHandlers[BinaryUtils.TypeArrayEnum] = new BinarySystemReader(ReadEnumArray);
         }
 
@@ -212,6 +212,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                 return WriteGuid;
             if (type == typeof (BinaryObject))
                 return WriteBinary;
+            if (type == typeof (BinaryEnum))
+                return WriteBinaryEnum;
             if (type == typeof (ArrayList))
                 return WriteArrayList;
             if (type == typeof(Hashtable))
@@ -257,11 +259,11 @@ namespace Apache.Ignite.Core.Impl.Binary
                 if (elemType == typeof(Guid?))
                     return WriteGuidArray;
                 // Enums.
-                if (elemType.IsEnum)
+                if (elemType.IsEnum || elemType == typeof(BinaryEnum))
                     return WriteEnumArray;
                 
                 // Object array.
-                if (elemType == typeof (object))
+                if (elemType == typeof (object) || elemType == typeof(IBinaryObject) || elemType == typeof(BinaryObject))
                     return WriteArray;
             }
 
@@ -329,13 +331,18 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Reads an object of predefined type.
         /// </summary>
-        public static T ReadSystemType<T>(byte typeId, BinaryReader ctx)
+        public static bool TryReadSystemType<T>(byte typeId, BinaryReader ctx, out T res)
         {
             var handler = ReadHandlers[typeId];
 
-            Debug.Assert(handler != null, "Cannot find predefined read handler: " + typeId);
-            
-            return handler.Read<T>(ctx);
+            if (handler == null)
+            {
+                res = default(T);
+                return false;
+            }
+
+            res = handler.Read<T>(ctx);
+            return true;
         }
         
         /// <summary>
@@ -629,9 +636,20 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         private static void WriteEnum(BinaryWriter ctx, object obj)
         {
+            ctx.WriteEnum(obj);
+        }
+
+        /// <summary>
+        /// Write enum.
+        /// </summary>
+        private static void WriteBinaryEnum(BinaryWriter ctx, object obj)
+        {
+            var binEnum = (BinaryEnum) obj;
+
             ctx.Stream.WriteByte(BinaryUtils.TypeEnum);
 
-            BinaryUtils.WriteEnum(ctx, obj);
+            ctx.WriteInt(binEnum.TypeId);
+            ctx.WriteInt(binEnum.EnumValue);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
index 1aed03f..1917f01 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -23,7 +23,9 @@ namespace Apache.Ignite.Core.Impl.Binary
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
     using System.IO;
+    using System.Linq;
     using System.Reflection;
     using System.Runtime.InteropServices;
     using System.Text;
@@ -1318,25 +1320,29 @@ namespace Apache.Ignite.Core.Impl.Binary
             }
 
             throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " +
-                enumType.Name);
+                                            enumType.Name);
         }
 
         /// <summary>
-        /// Read enum.
+        /// Gets the enum value by type id and int representation.
         /// </summary>
-        /// <param name="stream">Stream.</param>
-        /// <returns>Enumeration.</returns>
-        public static T ReadEnum<T>(IBinaryStream stream)
+        /// <typeparam name="T">Result type.</typeparam>
+        /// <param name="value">The value.</param>
+        /// <param name="typeId">The type identifier.</param>
+        /// <param name="marsh">The marshaller.</param>
+        /// <returns>value in form of enum, if typeId is known; value in for of int, if typeId is -1.</returns>
+        public static T GetEnumValue<T>(int value, int typeId, Marshaller marsh)
         {
-            if (!typeof(T).IsEnum || Enum.GetUnderlyingType(typeof(T)) == TypInt)
-            {
-                stream.ReadInt();
+            if (typeId == ObjTypeId)
+                return TypeCaster<T>.Cast(value);
 
-                return TypeCaster<T>.Cast(stream.ReadInt());
-            }
+            // All enums are user types
+            var desc = marsh.GetDescriptor(true, typeId);
 
-            throw new BinaryObjectException("Only Int32 underlying type is supported for enums: " +
-                                        typeof (T).Name);
+            if (desc == null || desc.Type == null)
+                throw new BinaryObjectException("Unknown enum type id: " + typeId);
+
+            return (T)Enum.ToObject(desc.Type, value);
         }
 
         /**
@@ -1387,52 +1393,6 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /**
-         * <summary>Check whether this is predefined type.</summary>
-         * <param name="hdr">Header.</param>
-         * <returns>True is this is one of predefined types with special semantics.</returns>
-         */
-        public static bool IsPredefinedType(byte hdr)
-        {
-            switch (hdr)
-            {
-                case TypeByte:
-                case TypeShort:
-                case TypeInt:
-                case TypeLong:
-                case TypeFloat:
-                case TypeDouble:
-                case TypeChar:
-                case TypeBool:
-                case TypeDecimal:
-                case TypeString:
-                case TypeGuid:
-                case TypeTimestamp:
-                case TypeEnum:
-                case TypeArrayByte:
-                case TypeArrayShort:
-                case TypeArrayInt:
-                case TypeArrayLong:
-                case TypeArrayFloat:
-                case TypeArrayDouble:
-                case TypeArrayChar:
-                case TypeArrayBool:
-                case TypeArrayDecimal:
-                case TypeArrayString:
-                case TypeArrayGuid:
-                case TypeArrayTimestamp:
-                case TypeArrayEnum:
-                case TypeArray:
-                case TypeCollection:
-                case TypeDictionary:
-                case TypeMapEntry:
-                case TypeBinary:
-                    return true;
-                default:
-                    return false;
-            }
-        }
-
-        /**
          * <summary>Convert type name.</summary>
          * <param name="typeName">Type name.</param>
          * <param name="converter">Converter.</param>
@@ -1534,6 +1494,23 @@ namespace Apache.Ignite.Core.Impl.Binary
             return id;
         }
 
+        /// <summary>
+        /// Gets the name of the type.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <returns>
+        /// Simple type name for non-generic types; simple type name with appended generic arguments for generic types.
+        /// </returns>
+        public static string GetTypeName(Type type)
+        {
+            if (!type.IsGenericType)
+                return type.Name;
+
+            var args = type.GetGenericArguments().Select(GetTypeName).Aggregate((x, y) => x + "," + y);
+
+            return string.Format(CultureInfo.InvariantCulture, "{0}[{1}]", type.Name, args);
+        }
+
         /**
          * <summary>Resolve field ID.</summary>
          * <param name="typeId">Type ID.</param>
@@ -1732,7 +1709,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                             IdMapper = CreateInstance<IBinaryIdMapper>(reader),
                             Serializer = CreateInstance<IBinarySerializer>(reader),
                             AffinityKeyFieldName = reader.ReadString(),
-                            KeepDeserialized = reader.ReadObject<bool?>()
+                            KeepDeserialized = reader.ReadObject<bool?>(),
+                            IsEnum = reader.ReadBoolean()
                         });
                     }
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/663e78dc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
index c00dad6..189cd50 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
@@ -20,12 +20,12 @@ namespace Apache.Ignite.Core.Impl.Binary
     using System;
     using System.Collections;
     using System.Collections.Generic;
+    using System.Diagnostics;
     using System.IO;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
     using Apache.Ignite.Core.Impl.Binary.Metadata;
     using Apache.Ignite.Core.Impl.Binary.Structure;
-    using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
     /// Binary writer implementation.
@@ -45,7 +45,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         private BinaryHandleDictionary<object, long> _hnds;
 
         /** Metadatas collected during this write session. */
-        private IDictionary<int, IBinaryType> _metas;
+        private IDictionary<int, BinaryType> _metas;
 
         /** Current type ID. */
         private int _curTypeId;
@@ -803,8 +803,28 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="val">Enum value.</param>
         public void WriteEnum<T>(T val)
         {
-            _stream.WriteByte(BinaryUtils.TypeEnum);
-            BinaryUtils.WriteEnum(this, val);
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                var desc = _marsh.GetDescriptor(val.GetType());
+
+                if (desc != null)
+                {
+                    var metaHnd = _marsh.GetBinaryTypeHandler(desc);
+
+                    _stream.WriteByte(BinaryUtils.TypeEnum);
+
+                    BinaryUtils.WriteEnum(this, val);
+
+                    SaveMetadata(desc, metaHnd.OnObjectWriteFinished());
+                }
+                else
+                {
+                    // Unregistered enum, write as serializable
+                    Write(new SerializableObjectHolder(val));
+                }
+            }
         }
 
         /// <summary>
@@ -817,10 +837,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             WriteFieldId(fieldName, BinaryUtils.TypeArrayEnum);
 
-            if (val == null)
-                WriteNullField();
-            else
-                WriteEnumArray0(val);
+            WriteEnumArray(val);
         }
 
         /// <summary>
@@ -830,24 +847,26 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="val">Enum array.</param>
         public void WriteEnumArray<T>(T[] val)
         {
-            if (val == null)
-                WriteNullRawField();
-            else
-                WriteEnumArray0(val);
+            WriteEnumArrayInternal(val, null);
         }
 
         /// <summary>
         /// Writes the enum array.
         /// </summary>
         /// <param name="val">The value.</param>
-        private void WriteEnumArray0<T>(T[] val)
+        /// <param name="elementTypeId">The element type id.</param>
+        public void WriteEnumArrayInternal(Array val, int? elementTypeId)
         {
-            _stream.WriteByte(BinaryUtils.TypeArrayEnum);
+            if (val == null)
+                WriteNullField();
+            else
+            {
+                _stream.WriteByte(BinaryUtils.TypeArrayEnum);
 
-            // typeof(T) can yield wrong results (string[] is object[], for example)
-            var elementType = val.GetType().GetElementType();  
+                var elTypeId = elementTypeId ?? BinaryUtils.GetEnumTypeId(val.GetType().GetElementType(), Marshaller);
 
-            BinaryUtils.WriteArray(val, this, BinaryUtils.GetEnumTypeId(elementType, Marshaller));
+                BinaryUtils.WriteArray(val, this, elTypeId);
+            }
         }
 
         /// <summary>
@@ -1051,12 +1070,20 @@ namespace Apache.Ignite.Core.Impl.Binary
                 return;
             }
 
+            // Handle enums.
+            if (type.IsEnum)
+            {
+                WriteEnum(obj);
+
+                return;
+            }
+
             // Handle special case for builder.
             if (WriteBuilderSpecials(obj))
                 return;
 
             // Suppose that we faced normal object and perform descriptor lookup.
-            IBinaryTypeDescriptor desc = type.IsEnum ? null : _marsh.GetDescriptor(type);
+            IBinaryTypeDescriptor desc = _marsh.GetDescriptor(type);
 
             if (desc != null)
             {
@@ -1356,9 +1383,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// Gets collected metadatas.
         /// </summary>
         /// <returns>Collected metadatas (if any).</returns>
-        internal IDictionary<int, IBinaryType> GetBinaryTypes()
+        internal ICollection<BinaryType> GetBinaryTypes()
         {
-            return _metas;
+            return _metas == null ? null : _metas.Values;
         }
 
         /// <summary>
@@ -1399,37 +1426,38 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Saves metadata for this session.
         /// </summary>
-        /// <param name="typeId">Type ID.</param>
-        /// <param name="typeName">Type name.</param>
-        /// <param name="affKeyFieldName">Affinity key field name.</param>
+        /// <param name="desc">The descriptor.</param>
         /// <param name="fields">Fields metadata.</param>
-        internal void SaveMetadata(int typeId, string typeName, string affKeyFieldName, IDictionary<string, int> fields)
+        internal void SaveMetadata(IBinaryTypeDescriptor desc, IDictionary<string, int> fields)
         {
+            Debug.Assert(desc != null);
+
             if (_metas == null)
             {
-                BinaryType meta =
-                    new BinaryType(typeId, typeName, fields, affKeyFieldName);
-
-                _metas = new Dictionary<int, IBinaryType>(1);
-
-                _metas[typeId] = meta;
+                _metas = new Dictionary<int, BinaryType>(1)
+                {
+                    {desc.TypeId, new BinaryType(desc, fields)}
+                };
             }
             else
             {
-                IBinaryType meta;
+                BinaryType meta;
 
-                if (_metas.TryGetValue(typeId, out meta))
+                if (_metas.TryGetValue(desc.TypeId, out meta))
                 {
-                    IDictionary<string, int> existingFields = ((BinaryType)meta).FieldsMap();
-
-                    foreach (KeyValuePair<string, int> field in fields)
+                    if (fields != null)
                     {
-                        if (!existingFields.ContainsKey(field.Key))
-                            existingFields[field.Key] = field.Value;
+                        IDictionary<string, int> existingFields = meta.GetFieldsMap();
+
+                        foreach (KeyValuePair<string, int> field in fields)
+                        {
+                            if (!existingFields.ContainsKey(field.Key))
+                                existingFields[field.Key] = field.Value;
+                        }
                     }
                 }
                 else
-                    _metas[typeId] = new BinaryType(typeId, typeName, fields, affKeyFieldName);
+                    _metas[desc.TypeId] = new BinaryType(desc, fields);
             }
         }
     }


Mime
View raw message