You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/29 07:11:57 UTC

[01/11] ignite git commit: .NET: Remove more dead code from old LINQ CompiledQuery

Repository: ignite
Updated Branches:
  refs/heads/ignite-5075 3858bb58f -> 32b43db7f


.NET: Remove more dead code from old LINQ CompiledQuery


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

Branch: refs/heads/ignite-5075
Commit: cfc74364c27ad06d38fc2bb40fdc442327e95285
Parents: bdd43ff
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 26 11:38:06 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 26 11:38:06 2017 +0300

----------------------------------------------------------------------
 .../Impl/CacheQueryExpressionVisitor.cs             | 12 +-----------
 .../Impl/CacheQueryModelVisitor.cs                  | 13 +------------
 .../dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs |  7 +++++--
 .../dotnet/Apache.Ignite.Linq/Impl/QueryData.cs     | 16 +---------------
 4 files changed, 8 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cfc74364/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
index 2d14ec4..8fa0b5d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryExpressionVisitor.cs
@@ -313,22 +313,12 @@ namespace Apache.Ignite.Linq.Impl
                 ResultBuilder.AppendFormat("{0}.{1}", Aliases.GetTableAlias(expression), fieldName);
             }
             else
-                AppendParameter(RegisterEvaluatedParameter(expression));
+                AppendParameter(ExpressionWalker.EvaluateExpression<object>(expression));
 
             return expression;
         }
 
         /// <summary>
-        /// Registers query parameter that is evaluated from a lambda expression argument.
-        /// </summary>
-        public object RegisterEvaluatedParameter(Expression expression)
-        {
-            _modelVisitor.ParameterExpressions.Add(expression);
-
-            return ExpressionWalker.EvaluateExpression<object>(expression);
-        }
-
-        /// <summary>
         /// Gets the name of the field from a member expression.
         /// </summary>
         private static string GetFieldName(MemberExpression expression, ICacheQueryableInternal queryable)

http://git-wip-us.apache.org/repos/asf/ignite/blob/cfc74364/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
index f74ccc7..f566caa 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
@@ -43,9 +43,6 @@ namespace Apache.Ignite.Linq.Impl
         private readonly List<object> _parameters = new List<object>();
 
         /** */
-        private readonly List<Expression> _parameterExpressions = new List<Expression>();
-
-        /** */
         private readonly AliasDictionary _aliases = new AliasDictionary();
 
         /// <summary>
@@ -63,7 +60,7 @@ namespace Apache.Ignite.Linq.Impl
 
             var qryText = _builder.ToString();
 
-            return new QueryData(qryText, _parameters, _parameterExpressions);
+            return new QueryData(qryText, _parameters);
         }
 
         /// <summary>
@@ -83,14 +80,6 @@ namespace Apache.Ignite.Linq.Impl
         }
 
         /// <summary>
-        /// Gets the parameters.
-        /// </summary>
-        public IList<Expression> ParameterExpressions
-        {
-            get { return _parameterExpressions; }
-        }
-
-        /// <summary>
         /// Gets the aliases.
         /// </summary>
         public AliasDictionary Aliases

http://git-wip-us.apache.org/repos/asf/ignite/blob/cfc74364/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
index 578c5da..9446af3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/MethodVisitor.cs
@@ -250,7 +250,8 @@ namespace Apache.Ignite.Linq.Impl
         /// <summary>
         /// Visits the SQL like expression.
         /// </summary>
-        private static void VisitSqlLike(MethodCallExpression expression, CacheQueryExpressionVisitor visitor, string likeFormat)
+        private static void VisitSqlLike(MethodCallExpression expression, CacheQueryExpressionVisitor visitor,
+            string likeFormat)
         {
             visitor.ResultBuilder.Append("(");
 
@@ -260,7 +261,9 @@ namespace Apache.Ignite.Linq.Impl
 
             var arg = expression.Arguments[0] as ConstantExpression;
 
-            var paramValue = arg != null ? arg.Value : visitor.RegisterEvaluatedParameter(expression.Arguments[0]);
+            var paramValue = arg != null
+                ? arg.Value
+                : ExpressionWalker.EvaluateExpression<object>(expression.Arguments[0]);
 
             visitor.Parameters.Add(paramValue);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/cfc74364/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
index 5424692..81b91d2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
@@ -33,24 +33,18 @@ namespace Apache.Ignite.Linq.Impl
         /** */
         private readonly string _queryText;
 
-        /** */
-        private readonly ICollection<Expression> _parameterExpressions;
-
         /// <summary>
         /// Initializes a new instance of the <see cref="QueryData"/> class.
         /// </summary>
         /// <param name="queryText">The query text.</param>
         /// <param name="parameters">The parameters.</param>
-        /// <param name="parameterExpressions"></param>
-        public QueryData(string queryText, ICollection<object> parameters, ICollection<Expression> parameterExpressions)
+        public QueryData(string queryText, ICollection<object> parameters)
         {
             Debug.Assert(queryText != null);
             Debug.Assert(parameters != null);
-            Debug.Assert(parameterExpressions != null);
 
             _queryText = queryText;
             _parameters = parameters;
-            _parameterExpressions = parameterExpressions;
         }
 
         /// <summary>
@@ -70,14 +64,6 @@ namespace Apache.Ignite.Linq.Impl
         }
 
         /// <summary>
-        /// Gets the parameter expressions.
-        /// </summary>
-        public ICollection<Expression> ParameterExpressions
-        {
-            get { return _parameterExpressions; }
-        }
-
-        /// <summary>
         /// Returns a <see cref="string" /> that represents this instance.
         /// </summary>
         /// <returns>


[09/11] ignite git commit: IGNITE-1925: Removed flaky test HadoopSkipListSelfTest.testLevel. Distribution itself looks fine. This closes #1678.

Posted by sb...@apache.org.
IGNITE-1925: Removed flaky test HadoopSkipListSelfTest.testLevel. Distribution itself looks fine. This closes #1678.


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

Branch: refs/heads/ignite-5075
Commit: e09b5a2dfb317698ba20f337e920c5e2be38a32d
Parents: b5c7b6f
Author: devozerov <vo...@gridgain.com>
Authored: Fri May 26 15:27:56 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri May 26 15:27:56 2017 +0300

----------------------------------------------------------------------
 .../collections/HadoopSkipListSelfTest.java     | 37 --------------------
 1 file changed, 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e09b5a2d/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/impl/shuffle/collections/HadoopSkipListSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/impl/shuffle/collections/HadoopSkipListSelfTest.java b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/impl/shuffle/collections/HadoopSkipListSelfTest.java
index 1138803..21575c5 100644
--- a/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/impl/shuffle/collections/HadoopSkipListSelfTest.java
+++ b/modules/hadoop/src/test/java/org/apache/ignite/internal/processors/hadoop/impl/shuffle/collections/HadoopSkipListSelfTest.java
@@ -20,7 +20,6 @@ package org.apache.ignite.internal.processors.hadoop.impl.shuffle.collections;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Deque;
 import java.util.Iterator;
@@ -45,47 +44,11 @@ import org.apache.ignite.internal.util.io.GridUnsafeDataInput;
 import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
 import org.apache.ignite.internal.util.typedef.X;
 
-import static java.lang.Math.abs;
-import static java.lang.Math.ceil;
-import static java.lang.Math.max;
-
 /**
  * Skip list tests.
  */
 public class HadoopSkipListSelfTest extends HadoopAbstractMapTest {
     /**
-     *
-     */
-    public void testLevel() {
-        Random rnd = new GridRandom();
-
-        int[] levelsCnts = new int[32];
-
-        int all = 10000;
-
-        for (int i = 0; i < all; i++) {
-            int level = HadoopSkipList.randomLevel(rnd);
-
-            levelsCnts[level]++;
-        }
-
-        X.println("Distribution: " + Arrays.toString(levelsCnts));
-
-        for (int level = 0; level < levelsCnts.length; level++) {
-            int exp = (level + 1) == levelsCnts.length ? 0 : all >>> (level + 1);
-
-            double precission = 0.72 / Math.max(32 >>> level, 1);
-
-            int sigma = max((int)ceil(precission * exp), 5);
-
-            X.println("Level: " + level + " exp: " + exp + " act: " + levelsCnts[level] + " precision: " + precission +
-                " sigma: " + sigma);
-
-            assertTrue(abs(exp - levelsCnts[level]) <= sigma); // Sometimes fails.
-        }
-    }
-
-    /**
      * @throws Exception On error.
      */
     public void testMapSimple() throws Exception {


[04/11] ignite git commit: .NET: Remove unused imports

Posted by sb...@apache.org.
.NET: Remove unused imports


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

Branch: refs/heads/ignite-5075
Commit: 22d108c076988dc2291fc78776e0473e0c457d91
Parents: d911848
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 26 12:07:46 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 26 12:07:46 2017 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/22d108c0/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
index 81b91d2..ae04a0b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs
@@ -20,7 +20,6 @@ namespace Apache.Ignite.Linq.Impl
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Linq;
-    using System.Linq.Expressions;
 
     /// <summary>
     /// Query data holder.


[05/11] ignite git commit: Merge remote-tracking branch 'origin/master'

Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/master'


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

Branch: refs/heads/ignite-5075
Commit: 279f35b156a74faec271f23ee589e0a54f7ac53d
Parents: 8a6bc9e 22d108c
Author: sboikov <sb...@gridgain.com>
Authored: Fri May 26 12:11:49 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri May 26 12:11:49 2017 +0300

----------------------------------------------------------------------
 modules/platforms/dotnet/Apache.Ignite.Linq/Impl/QueryData.cs | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------



[10/11] ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-5075

Posted by sb...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-5075


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

Branch: refs/heads/ignite-5075
Commit: 403b848d921bf24cb599c12fe923a658cc98ff86
Parents: 3858bb5 e09b5a2
Author: sboikov <sb...@gridgain.com>
Authored: Mon May 29 10:05:44 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon May 29 10:05:44 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/IgniteBinary.java    |  23 ++-
 .../org/apache/ignite/binary/BinaryObject.java  |   8 +
 .../org/apache/ignite/binary/BinaryType.java    |   5 +
 .../ignite/binary/BinaryTypeConfiguration.java  |  26 +++
 .../binary/BinaryCachingMetadataHandler.java    |   5 +
 .../internal/binary/BinaryClassDescriptor.java  |   4 +-
 .../ignite/internal/binary/BinaryContext.java   |  60 +++++--
 .../internal/binary/BinaryEnumObjectImpl.java   |  30 +++-
 .../internal/binary/BinaryFieldAccessor.java    |  10 ++
 .../ignite/internal/binary/BinaryMetadata.java  |  93 +++++++++-
 .../internal/binary/BinaryMetadataHandler.java  |   9 +
 .../binary/BinaryNoopMetadataHandler.java       |   5 +
 .../internal/binary/BinaryObjectExImpl.java     |   5 +
 .../internal/binary/BinaryReaderExImpl.java     |  18 ++
 .../ignite/internal/binary/BinaryTypeImpl.java  |  15 ++
 .../ignite/internal/binary/BinaryTypeProxy.java |   6 +
 .../ignite/internal/binary/BinaryUtils.java     | 104 ++++++++++-
 .../internal/binary/BinaryWriterExImpl.java     |  18 +-
 .../internal/binary/GridBinaryMarshaller.java   |   3 +
 .../binary/builder/BinaryBuilderSerializer.java |  10 +-
 .../binary/builder/BinaryObjectBuilderImpl.java |   2 +-
 .../binary/CacheObjectBinaryProcessor.java      |  21 ++-
 .../binary/CacheObjectBinaryProcessorImpl.java  |  72 +++++++-
 .../cache/binary/IgniteBinaryImpl.java          |  26 +++
 .../processors/cacheobject/NoOpBinary.java      |  12 ++
 .../platform/PlatformContextImpl.java           |  29 ++-
 .../binary/PlatformBinaryProcessor.java         |  25 +++
 .../communication/tcp/TcpCommunicationSpi.java  |   4 +-
 .../internal/binary/BinaryEnumsSelfTest.java    | 146 ++++++++++++++-
 .../binary/TestCachingMetadataHandler.java      |   5 +
 .../platform/PlatformComputeEchoTask.java       |  13 ++
 .../collections/HadoopSkipListSelfTest.java     |  37 ----
 .../Binary/BinaryBuilderSelfTest.cs             |  88 +++++++--
 .../Cache/Query/CacheLinqTest.cs                |  70 +++++++-
 .../Compute/ComputeApiTest.cs                   |  25 +++
 .../Binary/BinaryTypeConfiguration.cs           |   3 +-
 .../dotnet/Apache.Ignite.Core/Binary/IBinary.cs |  24 +++
 .../Apache.Ignite.Core/Binary/IBinaryObject.cs  |   8 +
 .../Apache.Ignite.Core/Binary/IBinaryType.cs    |   6 +
 .../Apache.Ignite.Core/Impl/Binary/Binary.cs    |  67 ++++++-
 .../Impl/Binary/BinaryEnum.cs                   |  11 +-
 .../Impl/Binary/BinaryObject.cs                 |  13 +-
 .../Impl/Binary/BinaryProcessor.cs              |  65 ++++++-
 .../Impl/Binary/BinaryReader.cs                 |  10 +-
 .../Impl/Binary/BinarySystemHandlers.cs         |  25 +--
 .../Impl/Binary/BinaryUtils.cs                  |  19 ++
 .../Impl/Binary/BinaryWriter.cs                 |   4 +-
 .../Impl/Binary/Marshaller.cs                   |  88 ++++-----
 .../Impl/Binary/Metadata/BinaryType.cs          | 179 ++++++++++++++++++-
 .../Impl/Binary/Metadata/BinaryTypeHolder.cs    |  44 +++--
 .../Apache.Ignite.Linq.csproj                   |   3 +
 .../Apache.Ignite.Linq/CacheExtensions.cs       |  65 +++++++
 .../Impl/CacheQueryExpressionVisitor.cs         |  12 +-
 .../Impl/CacheQueryModelVisitor.cs              |  73 ++++++--
 .../Apache.Ignite.Linq/Impl/CacheQueryParser.cs |  21 ++-
 .../Impl/Dml/RemoveAllExpressionNode.cs         |  88 +++++++++
 .../Impl/Dml/RemoveAllResultOperator.cs         |  61 +++++++
 .../Apache.Ignite.Linq/Impl/MethodVisitor.cs    |   7 +-
 .../dotnet/Apache.Ignite.Linq/Impl/QueryData.cs |  17 +-
 .../dotnet/Apache.Ignite.sln.DotSettings        |   1 +
 .../dotnet/Apache.Ignite/Apache.Ignite.csproj   |   1 -
 .../Apache.Ignite/Service/ServiceDescription.cs |  32 ----
 62 files changed, 1707 insertions(+), 272 deletions(-)
----------------------------------------------------------------------



[03/11] ignite git commit: TcpCommunicationSpi: increased default idle timeout.

Posted by sb...@apache.org.
TcpCommunicationSpi: increased default idle timeout.


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

Branch: refs/heads/ignite-5075
Commit: 8a6bc9e61677e3b1b75684233a4693921e991db7
Parents: d911848
Author: sboikov <sb...@gridgain.com>
Authored: Fri May 26 12:07:40 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Fri May 26 12:07:40 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8a6bc9e6/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
index 5ec9a6e..2e35c6e 100755
--- a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
@@ -267,8 +267,8 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter implements Communicati
     /** Default port which node sets listener for shared memory connections (value is <tt>48100</tt>). */
     public static final int DFLT_SHMEM_PORT = -1;
 
-    /** Default idle connection timeout (value is <tt>30000</tt>ms). */
-    public static final long DFLT_IDLE_CONN_TIMEOUT = 30000;
+    /** Default idle connection timeout (value is <tt>10</tt>min). */
+    public static final long DFLT_IDLE_CONN_TIMEOUT = 10 * 60_000;
 
     /** Default socket send and receive buffer size. */
     public static final int DFLT_SOCK_BUF_SIZE = 32 * 1024;


[06/11] ignite git commit: IGNITE-4904 .NET: DML Delete via LINQ

Posted by sb...@apache.org.
IGNITE-4904 .NET: DML Delete via LINQ

This closes #2009


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

Branch: refs/heads/ignite-5075
Commit: d38ca8b1004effefa5126981f434649d26db1e68
Parents: 279f35b
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 26 13:02:01 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 26 13:02:01 2017 +0300

----------------------------------------------------------------------
 .../Cache/Query/CacheLinqTest.cs                | 70 +++++++++++++++-
 .../Apache.Ignite.Linq.csproj                   |  3 +
 .../Apache.Ignite.Linq/CacheExtensions.cs       | 65 +++++++++++++++
 .../Impl/CacheQueryModelVisitor.cs              | 60 +++++++++++--
 .../Apache.Ignite.Linq/Impl/CacheQueryParser.cs | 21 ++++-
 .../Impl/Dml/RemoveAllExpressionNode.cs         | 88 ++++++++++++++++++++
 .../Impl/Dml/RemoveAllResultOperator.cs         | 61 ++++++++++++++
 .../dotnet/Apache.Ignite.sln.DotSettings        |  1 +
 8 files changed, 359 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
index cb3fece..b603d75 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs
@@ -37,6 +37,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Common;
     using Apache.Ignite.Linq;
     using NUnit.Framework;
 
@@ -1269,7 +1270,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var cache = GetPersonCache();
 
             // Check regular query
-            var query = (ICacheQueryable) cache.AsCacheQueryable(new QueryOptions
+            var query = cache.AsCacheQueryable(new QueryOptions
             {
                 Local = true,
                 PageSize = 999,
@@ -1277,7 +1278,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
                 Timeout = TimeSpan.FromSeconds(2.5),
                 ReplicatedOnly = true,
                 Colocated = true
-            }).Where(x => x.Key > 10);
+            }).Where(x => x.Key > 10).ToCacheQueryable();
 
             Assert.AreEqual(cache.Name, query.CacheName);
             Assert.AreEqual(cache.Ignite, query.Ignite);
@@ -1325,7 +1326,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
             var distrQuery = cache.AsCacheQueryable(new QueryOptions {EnableDistributedJoins = true})
                 .Where(x => x.Key > 10 && x.Value.Age > 20 && x.Value.Name.Contains("x"));
 
-            query = (ICacheQueryable) distrQuery;
+            query = distrQuery.ToCacheQueryable();
 
             Assert.IsTrue(query.GetFieldsQuery().EnableDistributedJoins);
 
@@ -1424,6 +1425,69 @@ namespace Apache.Ignite.Core.Tests.Cache.Query
         }
 
         /// <summary>
+        /// Tests the RemoveAll extension.
+        /// </summary>
+        [Test]
+        public void TestRemoveAll()
+        {
+            // Use new cache to avoid touching static data.
+            var cache = Ignition.GetIgnite().CreateCache<int, Person>(new CacheConfiguration("deleteAllTest",
+                    new QueryEntity(typeof(int), typeof(Person))));
+
+            Enumerable.Range(1, 10).ToList().ForEach(x => cache.Put(x, new Person(x, x.ToString())));
+            
+            var queryable = cache.AsCacheQueryable();
+
+            Func<int[]> getKeys = () => cache.Select(x => x.Key).OrderBy(x => x).ToArray();
+
+            // Without predicate.
+            var res = queryable.Where(x => x.Key < 3).RemoveAll();
+            Assert.AreEqual(2, res);
+            Assert.AreEqual(Enumerable.Range(3, 8), getKeys());
+
+            // With predicate.
+            res = queryable.RemoveAll(x => x.Key < 7);
+            Assert.AreEqual(4, res);
+            Assert.AreEqual(Enumerable.Range(7, 4), getKeys());
+
+            // Subquery-style join.
+            var ids = GetPersonCache().AsCacheQueryable().Where(x => x.Key == 7).Select(x => x.Key);
+
+            res = queryable.Where(x => ids.Contains(x.Key)).RemoveAll();
+            Assert.AreEqual(1, res);
+            Assert.AreEqual(Enumerable.Range(8, 3), getKeys());
+
+            // Row number limit.
+            res = queryable.Take(2).RemoveAll();
+            Assert.AreEqual(2, res);
+            Assert.AreEqual(1, getKeys().Length);
+
+            // Unconditional.
+            queryable.RemoveAll();
+            Assert.AreEqual(0, cache.GetSize());
+
+            // Skip is not supported with DELETE.
+            var nex = Assert.Throws<NotSupportedException>(() => queryable.Skip(1).RemoveAll());
+            Assert.AreEqual(
+                "RemoveAll can not be combined with result operators (other than Take): SkipResultOperator",
+                nex.Message);
+
+            // Multiple result operators are not supported with DELETE.
+            nex = Assert.Throws<NotSupportedException>(() => queryable.Skip(1).Take(1).RemoveAll());
+            Assert.AreEqual(
+                "RemoveAll can not be combined with result operators (other than Take): SkipResultOperator, " +
+                "TakeResultOperator, RemoveAllResultOperator", nex.Message);
+
+            // Joins are not supported in H2.
+            var qry = queryable
+                .Where(x => x.Key == 7)
+                .Join(GetPersonCache().AsCacheQueryable(), p => p.Key, p => p.Key, (p1, p2) => p1);
+
+            var ex = Assert.Throws<IgniteException>(() => qry.RemoveAll());
+            Assert.AreEqual("Failed to parse query", ex.Message.Substring(0, 21));
+        }
+
+        /// <summary>
         /// Gets the person cache.
         /// </summary>
         /// <returns></returns>

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
index a7ec402..f4949d7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Apache.Ignite.Linq.csproj
@@ -63,6 +63,8 @@
     <Compile Include="Impl\CacheQueryExpressionVisitor.cs" />
     <Compile Include="Impl\CacheQueryModelVisitor.cs" />
     <Compile Include="Impl\CacheQueryParser.cs" />
+    <Compile Include="Impl\Dml\RemoveAllExpressionNode.cs" />
+    <Compile Include="Impl\Dml\RemoveAllResultOperator.cs" />
     <Compile Include="Impl\ICacheQueryableInternal.cs" />
     <Compile Include="Impl\MethodVisitor.cs" />
     <Compile Include="Impl\QueryData.cs" />
@@ -83,6 +85,7 @@
       <Name>Apache.Ignite.Core</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
index 2c609c6..f759dbb 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/CacheExtensions.cs
@@ -17,11 +17,15 @@
 
 namespace Apache.Ignite.Linq
 {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
     using System.Linq;
+    using System.Linq.Expressions;
     using Apache.Ignite.Core.Cache;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Linq.Impl;
+    using Apache.Ignite.Linq.Impl.Dml;
 
     /// <summary>
     /// Extensions methods for <see cref="ICache{TK,TV}"/>.
@@ -126,5 +130,66 @@ namespace Apache.Ignite.Linq
 
             return new CacheQueryable<TKey, TValue>(cache, queryOptions);
         }
+
+        /// <summary>
+        /// Casts this query to <see cref="ICacheQueryable"/>.
+        /// </summary>
+        public static ICacheQueryable ToCacheQueryable<T>(this IQueryable<T> query)
+        {
+            IgniteArgumentCheck.NotNull(query, "query");
+
+            return (ICacheQueryable) query;
+        }
+
+        /// <summary>
+        /// Removes all rows that are matched by the specified query.
+        /// <para />
+        /// This method results in "DELETE FROM" distributed SQL query, performing bulk delete 
+        /// (as opposed to fetching all rows locally).
+        /// </summary>
+        /// <typeparam name="TKey">Key type.</typeparam>
+        /// <typeparam name="TValue">Value type.</typeparam>
+        /// <param name="query">The query.</param>
+        /// <returns>Affected row count.</returns>
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods",
+            Justification = "Validation is present.")]
+        public static int RemoveAll<TKey, TValue>(this IQueryable<ICacheEntry<TKey, TValue>> query)
+        {
+            IgniteArgumentCheck.NotNull(query, "query");
+
+            var method = RemoveAllExpressionNode.RemoveAllMethodInfo.MakeGenericMethod(typeof(TKey), typeof(TValue));
+
+            return query.Provider.Execute<int>(Expression.Call(null, method, query.Expression));
+        }
+
+        /// <summary>
+        /// Deletes all rows that are matched by the specified query.
+        /// <para />
+        /// This method results in "DELETE FROM" distributed SQL query, performing bulk delete
+        /// (as opposed to fetching all rows locally).
+        /// </summary>
+        /// <typeparam name="TKey">Key type.</typeparam>
+        /// <typeparam name="TValue">Value type.</typeparam>
+        /// <param name="query">The query.</param>
+        /// <param name="predicate">The predicate.</param>
+        /// <returns>
+        /// Affected row count.
+        /// </returns>
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
+            Justification = "Only specified type of predicate is valid.")]
+        [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods",
+            Justification = "Validation is present.")]
+        public static int RemoveAll<TKey, TValue>(this IQueryable<ICacheEntry<TKey, TValue>> query, 
+            Expression<Func<ICacheEntry<TKey, TValue>, bool>> predicate)
+        {
+            IgniteArgumentCheck.NotNull(query, "query");
+            IgniteArgumentCheck.NotNull(predicate, "predicate");
+
+            var method = RemoveAllExpressionNode.RemoveAllPredicateMethodInfo
+                .MakeGenericMethod(typeof(TKey), typeof(TValue));
+
+            return query.Provider.Execute<int>(Expression.Call(null, method, query.Expression,
+                Expression.Quote(predicate)));
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
index f566caa..12b9502 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Linq.Impl
     using System.Linq;
     using System.Linq.Expressions;
     using System.Text;
+    using Apache.Ignite.Linq.Impl.Dml;
     using Remotion.Linq;
     using Remotion.Linq.Clauses;
     using Remotion.Linq.Clauses.Expressions;
@@ -100,22 +101,69 @@ namespace Apache.Ignite.Linq.Impl
         {
             _aliases.Push();
 
-            // SELECT
-            _builder.Append("select ");
+            var hasDelete = VisitRemoveOperator(queryModel);
 
-            // TOP 1 FLD1, FLD2
-            VisitSelectors(queryModel, includeAllFields);
+            if (!hasDelete)
+            {
+                // SELECT
+                _builder.Append("select ");
+
+                // TOP 1 FLD1, FLD2
+                VisitSelectors(queryModel, includeAllFields);
+            }
 
             // FROM ... WHERE ... JOIN ...
             base.VisitQueryModel(queryModel);
 
-            // UNION ...
-            ProcessResultOperatorsEnd(queryModel);
+            if (!hasDelete)
+            {
+                // UNION ...
+                ProcessResultOperatorsEnd(queryModel);
+            }
 
             _aliases.Pop();
         }
 
         /// <summary>
+        /// Visits the remove operator. Returns true if it is present.
+        /// </summary>
+        private bool VisitRemoveOperator(QueryModel queryModel)
+        {
+            var resultOps = queryModel.ResultOperators;
+
+            if (resultOps.LastOrDefault() is RemoveAllResultOperator)
+            {
+                _builder.Append("delete ");
+
+                if (resultOps.Count == 2)
+                {
+                    var resOp = resultOps[0] as TakeResultOperator;
+
+                    if (resOp == null)
+                    {
+                        throw new NotSupportedException(
+                            "RemoveAll can not be combined with result operators (other than Take): " +
+                            resultOps[0].GetType().Name);
+                    }
+
+                    _builder.Append("top ");
+                    BuildSqlExpression(resOp.Count);
+                    _builder.Append(" ");
+                }
+                else if (resultOps.Count > 2)
+                {
+                    throw new NotSupportedException(
+                        "RemoveAll can not be combined with result operators (other than Take): " +
+                        string.Join(", ", resultOps.Select(x => x.GetType().Name)));
+                }
+
+                return true;
+            }
+                
+            return false;
+        }
+
+        /// <summary>
         /// Visits the selectors.
         /// </summary>
         public void VisitSelectors(QueryModel queryModel, bool includeAllFields)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
index 794ef2e..17ec0a3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryParser.cs
@@ -18,10 +18,12 @@
 namespace Apache.Ignite.Linq.Impl
 {
     using System.Threading;
+    using Apache.Ignite.Linq.Impl.Dml;
     using Remotion.Linq.Parsing.ExpressionVisitors.Transformation;
     using Remotion.Linq.Parsing.ExpressionVisitors.TreeEvaluation;
     using Remotion.Linq.Parsing.Structure;
     using Remotion.Linq.Parsing.Structure.ExpressionTreeProcessors;
+    using Remotion.Linq.Parsing.Structure.NodeTypeProviders;
 
     /// <summary>
     /// Cache query parser.
@@ -49,12 +51,29 @@ namespace Apache.Ignite.Linq.Impl
 
             var proc = CreateCompoundProcessor(transformerRegistry);
 
-            var parser = new ExpressionTreeParser(ExpressionTreeParser.CreateDefaultNodeTypeProvider(), proc);
+            var parser = new ExpressionTreeParser(CreateNodeTypeProvider(), proc);
 
             return new QueryParser(parser);
         }
 
         /// <summary>
+        /// Creates the node type provider.
+        /// </summary>
+        private static INodeTypeProvider CreateNodeTypeProvider()
+        {
+            var methodInfoRegistry = MethodInfoBasedNodeTypeRegistry.CreateFromRelinqAssembly();
+
+            methodInfoRegistry.Register(RemoveAllExpressionNode.GetSupportedMethods(), 
+                typeof(RemoveAllExpressionNode));
+
+            return new CompoundNodeTypeProvider(new INodeTypeProvider[]
+            {
+                methodInfoRegistry,
+                MethodNameBasedNodeTypeRegistry.CreateFromRelinqAssembly()
+            });
+        }
+
+        /// <summary>
         /// Creates CompoundExpressionTreeProcessor.
         /// </summary>
         private static CompoundExpressionTreeProcessor CreateCompoundProcessor(

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
new file mode 100644
index 0000000..53674ac
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllExpressionNode.cs
@@ -0,0 +1,88 @@
+/*
+ * 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.Linq.Impl.Dml
+{
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+    using Apache.Ignite.Core.Cache;
+    using Remotion.Linq.Clauses;
+    using Remotion.Linq.Parsing.Structure.IntermediateModel;
+
+    /// <summary>
+    /// Represents a <see cref="MethodCallExpression"/> for 
+    /// <see cref="CacheLinqExtensions.RemoveAll{TKey,TValue}(IQueryable{ICacheEntry{TKey,TValue}})"/>.
+    /// When user calls RemoveAll, this node is generated.
+    /// </summary>
+    internal sealed class RemoveAllExpressionNode : ResultOperatorExpressionNodeBase
+    {
+        /** */
+        private static readonly MethodInfo[] RemoveAllMethodInfos = typeof(CacheLinqExtensions)
+            .GetMethods().Where(x => x.Name == "RemoveAll").ToArray();
+
+        /// <summary>
+        /// The RemoveAll() method.
+        /// </summary>
+        public static readonly MethodInfo RemoveAllMethodInfo =
+            RemoveAllMethodInfos.Single(x => x.GetParameters().Length == 1);
+
+        /// <summary>
+        /// The RemoveAll(pred) method.
+        /// </summary>
+        public static readonly MethodInfo RemoveAllPredicateMethodInfo =
+            RemoveAllMethodInfos.Single(x => x.GetParameters().Length == 2);
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RemoveAllExpressionNode"/> class.
+        /// </summary>
+        /// <param name="parseInfo">The parse information.</param>
+        /// <param name="optionalPredicate">The optional predicate.</param>
+        /// <param name="optionalSelector">The optional selector.</param>
+        public RemoveAllExpressionNode(MethodCallExpressionParseInfo parseInfo,
+            LambdaExpression optionalPredicate, LambdaExpression optionalSelector)
+            : base(parseInfo, optionalPredicate, optionalSelector)
+        {
+            // No-op.
+        }
+
+        /** <inheritdoc /> */
+        [ExcludeFromCodeCoverage]
+        public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved,
+            ClauseGenerationContext clauseGenerationContext)
+        {
+            throw CreateResolveNotSupportedException();
+        }
+
+        /** <inheritdoc /> */
+        protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
+        {
+            return new RemoveAllResultOperator();
+        }
+
+        /// <summary>
+        /// Gets the supported methods.
+        /// </summary>
+        public static IEnumerable<MethodInfo> GetSupportedMethods()
+        {
+            yield return RemoveAllMethodInfo;
+            yield return RemoveAllPredicateMethodInfo;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
new file mode 100644
index 0000000..76789cb
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/Dml/RemoveAllResultOperator.cs
@@ -0,0 +1,61 @@
+/*
+ * 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.Linq.Impl.Dml
+{
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using Apache.Ignite.Core.Cache;
+    using Remotion.Linq.Clauses;
+    using Remotion.Linq.Clauses.ResultOperators;
+    using Remotion.Linq.Clauses.StreamedData;
+
+    /// <summary>
+    /// Represents an operator for <see cref="CacheLinqExtensions.RemoveAll{TK,TV}(IQueryable{ICacheEntry{TK,TV}})"/>.
+    /// </summary>
+    internal sealed class RemoveAllResultOperator : ValueFromSequenceResultOperatorBase
+    {
+        /** <inheritdoc /> */
+        public override IStreamedDataInfo GetOutputDataInfo(IStreamedDataInfo inputInfo)
+        {
+            return new StreamedScalarValueInfo(typeof(int));
+        }
+
+        /** <inheritdoc /> */
+        [ExcludeFromCodeCoverage]
+        public override ResultOperatorBase Clone(CloneContext cloneContext)
+        {
+            return new RemoveAllResultOperator();
+        }
+
+        /** <inheritdoc /> */
+        [ExcludeFromCodeCoverage]
+        public override void TransformExpressions(Func<Expression, Expression> transformation)
+        {
+            // No-op.
+        }
+
+        /** <inheritdoc /> */
+        [ExcludeFromCodeCoverage]
+        public override StreamedValue ExecuteInMemory<T>(StreamedSequence sequence)
+        {
+            throw new NotSupportedException("RemoveAll is not supported for in-memory sequences.");
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d38ca8b1/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
index 078e9fb..9d5b728 100644
--- a/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
+++ b/modules/platforms/dotnet/Apache.Ignite.sln.DotSettings
@@ -7,4 +7,5 @@
 	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">DO_NOT_SHOW</s:String>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
 </wpf:ResourceDictionary>
\ No newline at end of file


[11/11] ignite git commit: ignite-5075

Posted by sb...@apache.org.
ignite-5075


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

Branch: refs/heads/ignite-5075
Commit: 32b43db7f56dbc5ce7e3f0b6788a48fbd878cbf2
Parents: 403b848
Author: sboikov <sb...@gridgain.com>
Authored: Mon May 29 10:11:48 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Mon May 29 10:11:48 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/processors/affinity/GridAffinityProcessor.java | 2 +-
 .../ignite/internal/processors/cache/GridCacheAffinityManager.java | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/32b43db7/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityProcessor.java
index b137d29..e57cf54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityProcessor.java
@@ -395,7 +395,7 @@ public class GridAffinityProcessor extends GridProcessorAdapter {
                     new GridAffinityAssignment(topVer, assign0.assignment(), assign0.idealAssignment());
 
                 AffinityInfo info = new AffinityInfo(
-                    cctx.group().config().getAffinity(),
+                    cctx.config().getAffinity(),
                     cctx.config().getAffinityMapper(),
                     assign,
                     cctx.cacheObjectContext());

http://git-wip-us.apache.org/repos/asf/ignite/blob/32b43db7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
index 71df0eb..702b848 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
@@ -58,7 +58,7 @@ public class GridCacheAffinityManager extends GridCacheManagerAdapter {
 
     /** {@inheritDoc} */
     @Override public void start0() throws IgniteCheckedException {
-        affFunction = cctx.group().affinityFunction();
+        affFunction = cctx.config().getAffinity();
         affMapper = cctx.config().getAffinityMapper();
 
         aff = cctx.group().affinity();


[07/11] ignite git commit: IGNITE-4575: Improved binary enums support. This closes #1968.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 841972d..7ab69e9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryObject.cs
@@ -65,6 +65,14 @@ namespace Apache.Ignite.Core.Binary
         int EnumValue { get; }
 
         /// <summary>
+        /// Gets the name of the underlying enum value.
+        /// </summary>
+        /// <value>
+        /// The name of the enum value.
+        /// </value>
+        string EnumName { get; }
+
+        /// <summary>
         /// Creates a new <see cref="IBinaryObjectBuilder"/> based on this object.
         /// <para />
         /// This is equivalent to <see cref="IBinary.GetBuilder(IBinaryObject)"/>.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 bec863f..df6693d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinaryType.cs
@@ -61,5 +61,11 @@ namespace Apache.Ignite.Core.Binary
         /// Gets the type identifier.
         /// </summary>
         int TypeId { get; }
+
+        /// <summary>
+        /// Gets the enum values.
+        /// Only valid when <see cref="IsEnum"/> is true.
+        /// </summary>
+        IEnumerable<IBinaryObject> GetEnumValues();
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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
index 4f3156c..bcf6c2d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Binary.cs
@@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 {
     using System;
     using System.Collections.Generic;
+    using System.Diagnostics;
     using System.IO;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Common;
@@ -165,7 +166,8 @@ namespace Apache.Ignite.Core.Impl.Binary
         public IBinaryObject BuildEnum(Type type, int value)
         {
             IgniteArgumentCheck.NotNull(type, "type");
-            IgniteArgumentCheck.Ensure(type.IsEnum, "type", "Type should be an Enum.");
+            IgniteArgumentCheck.Ensure(BinaryUtils.IsIgniteEnum(type), "type", 
+                "Type should be an Enum.");
             
             var desc = Marshaller.GetDescriptor(type);
 
@@ -176,15 +178,53 @@ namespace Apache.Ignite.Core.Impl.Binary
             return new BinaryEnum(desc.TypeId, value, Marshaller);
         }
 
+        /** <inheritDoc /> */
+        public IBinaryObject BuildEnum(string typeName, string valueName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+            IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+            var desc = Marshaller.GetDescriptor(typeName);
+
+            IgniteArgumentCheck.Ensure(desc.IsEnum, "typeName", "Type should be an Enum.");
+
+            _marsh.PutBinaryType(desc);
+
+            var value = GetEnumValueAsInt(typeName, valueName, desc);
+
+            return new BinaryEnum(desc.TypeId, value, Marshaller);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryObject BuildEnum(Type type, string valueName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+            var desc = Marshaller.GetDescriptor(type);
+
+            IgniteArgumentCheck.Ensure(desc.IsEnum, "typeName", "Type should be an Enum.");
+
+            _marsh.PutBinaryType(desc);
+
+            var value = GetEnumValueAsInt(type.ToString(), valueName, desc);
+
+            return new BinaryEnum(desc.TypeId, value, Marshaller);
+        }
+
+        /** <inheritDoc /> */
+        public IBinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
+
+            return Marshaller.Ignite.BinaryProcessor.RegisterEnum(typeName, values);
+        }
+
         /// <summary>
         /// Marshaller.
         /// </summary>
         internal Marshaller Marshaller
         {
-            get
-            {
-                return _marsh;
-            }
+            get { return _marsh; }
         }
 
         /// <summary>
@@ -199,5 +239,22 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             return new BinaryObjectBuilder(this, parent, obj, desc);
         }
+
+        /// <summary>
+        /// Gets the enum value as int.
+        /// </summary>
+        private int GetEnumValueAsInt(string typeName, string valueName, IBinaryTypeDescriptor desc)
+        {
+            var type = Marshaller.GetBinaryType(desc.TypeId);
+
+            var value = type.GetEnumValue(valueName);
+
+            IgniteArgumentCheck.Ensure(value != null, "valueName",
+                string.Format("Enum '{0}' does not have a value {1}", typeName, valueName));
+
+            Debug.Assert(value.HasValue);
+
+            return value.Value;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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
index 710cf17..2bc4bdf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryEnum.cs
@@ -88,6 +88,12 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /** <inheritdoc /> */
+        public string EnumName
+        {
+            get { return _marsh.GetBinaryType(_typeId).GetEnumName(_enumValue); }
+        }
+
+        /** <inheritdoc /> */
         public IBinaryObjectBuilder ToBuilder()
         {
             throw new NotSupportedException("Builder cannot be created for enum.");
@@ -136,11 +142,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                 return string.Format("BinaryEnum [typeId={0}, enumValue={1}]", _typeId, _enumValue);
             }
 
-            var desc = _marsh.GetDescriptor(true, _typeId);
-            var enumValueName = desc != null && desc.Type != null ? Enum.GetName(desc.Type, _enumValue) : null;
-
             return string.Format("{0} [typeId={1}, enumValue={2}, enumValueName={3}]",
-                meta.TypeName, _typeId, _enumValue, enumValueName);
+                meta.TypeName, _typeId, _enumValue, EnumName);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 480e0e6..8c5cee6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObject.cs
@@ -131,7 +131,18 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             get
             {
-                throw new NotSupportedException("IBinaryObject.Value is only supported for enums. " +
+                throw new NotSupportedException("IBinaryObject.EnumValue is only supported for enums. " +
+                    "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
+            }
+        }
+
+        /** <inheritdoc /> */
+        [ExcludeFromCodeCoverage]
+        public string EnumName
+        {
+            get
+            {
+                throw new NotSupportedException("IBinaryObject.EnumName is only supported for enums. " +
                     "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
index 72a1d5b..f48bcc0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
@@ -24,7 +24,7 @@ namespace Apache.Ignite.Core.Impl.Binary
     using Apache.Ignite.Core.Impl.Unmanaged;
 
     /// <summary>
-    /// Binary metadata processor.
+    /// Binary metadata processor, delegates to PlatformBinaryProcessor in Java.
     /// </summary>
     internal class BinaryProcessor : PlatformTarget
     {
@@ -38,7 +38,8 @@ namespace Apache.Ignite.Core.Impl.Binary
             PutMeta = 3,
             GetSchema = 4,
             RegisterType = 5,
-            GetType = 6
+            GetType = 6,
+            RegisterEnum = 7
         }
 
         /// <summary>
@@ -54,9 +55,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Gets metadata for specified type.
         /// </summary>
-        public IBinaryType GetBinaryType(int typeId)
+        public BinaryType GetBinaryType(int typeId)
         {
-            return DoOutInOp<IBinaryType>((int) Op.GetMeta,
+            return DoOutInOp((int) Op.GetMeta,
                 writer => writer.WriteInt(typeId),
                 stream =>
                 {
@@ -126,8 +127,27 @@ namespace Apache.Ignite.Core.Impl.Binary
                         w.WriteInt(field.Value.FieldId);
                     }
 
+                    // Enum data
                     w.WriteBoolean(meta.IsEnum);
 
+                    if (meta.IsEnum)
+                    {
+                        if (meta.EnumValuesMap != null)
+                        {
+                            w.WriteInt(meta.EnumValuesMap.Count);
+
+                            foreach (var pair in meta.EnumValuesMap)
+                            {
+                                w.WriteString(pair.Key);
+                                w.WriteInt(pair.Value);
+                            }
+                        }
+                        else
+                        {
+                            w.WriteInt(0);
+                        }
+                    }
+
                     // Send schemas
                     var desc = meta.Descriptor;
                     Debug.Assert(desc != null);
@@ -175,6 +195,43 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Registers the enum.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="values">The values.</param>
+        /// <returns>Resulting binary type.</returns>
+        public BinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
+        {
+            Debug.Assert(typeName != null);
+
+            return DoOutInOp((int) Op.RegisterEnum, w =>
+            {
+                w.WriteString(typeName);
+
+                if (values == null)
+                {
+                    w.WriteInt(0);
+                }
+                else
+                {
+                    var countPos = w.Stream.Position;
+                    w.WriteInt(0);
+                    var count = 0;
+
+                    foreach (var enumPair in values)
+                    {
+                        w.WriteString(enumPair.Key);
+                        w.WriteInt(enumPair.Value);
+
+                        count++;
+                    }
+
+                    w.Stream.WriteInt(countPos, count);
+                }
+            }, s => s.ReadBool() ? new BinaryType(Marshaller.StartUnmarshal(s)) : null);
+        }
+
+        /// <summary>
         /// Gets the type by id.
         /// </summary>
         /// <param name="id">The identifier.</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 a5c6814..73a0456 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryReader.cs
@@ -401,6 +401,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                     return default(T);
 
                 case BinaryUtils.TypeEnum:
+                case BinaryUtils.TypeBinaryEnum:
                     // Never read enums in binary mode when reading a field (we do not support half-binary objects)
                     return ReadEnum0<T>(this, false);  
 
@@ -411,9 +412,9 @@ namespace Apache.Ignite.Core.Impl.Binary
                     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));
+                    throw new BinaryObjectException(string.Format(
+                        "Invalid header on enum deserialization. Expected: {0} or {1} or {2} but was: {3}",
+                            BinaryUtils.TypeEnum, BinaryUtils.TypeBinaryEnum, BinaryUtils.HdrFull, hdr));
             }
         }
 
@@ -571,6 +572,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                     return true;
 
                 case BinaryUtils.TypeEnum:
+                case BinaryUtils.TypeBinaryEnum:
                     res = ReadEnum0<T>(this, _mode != BinaryMode.Deserialize);
 
                     return true;
@@ -994,7 +996,9 @@ namespace Apache.Ignite.Core.Impl.Binary
             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/b5c7b6f5/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 1dfc3b6..95a0be3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinarySystemHandlers.cs
@@ -255,7 +255,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                 if (elemType == typeof(Guid?))
                     return new BinarySystemWriteHandler<Guid?[]>(WriteGuidArray, true);
                 // Enums.
-                if (IsIntEnum(elemType) || elemType == typeof(BinaryEnum))
+                if (BinaryUtils.IsIgniteEnum(elemType) || elemType == typeof(BinaryEnum))
                     return new BinarySystemWriteHandler<object>(WriteEnumArray, true);
 
                 // Object array.
@@ -266,23 +266,6 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
-        /// Determines whether specified type is an enum which fits into Int32.
-        /// </summary>
-        private static bool IsIntEnum(Type type)
-        {
-            if (!type.IsEnum)
-                return false;
-
-            var underlyingType = Enum.GetUnderlyingType(type);
-
-            return underlyingType == typeof(int) 
-                || underlyingType == typeof(short)
-                || underlyingType == typeof(ushort)
-                || underlyingType == typeof(byte)
-                || underlyingType == typeof(sbyte);
-        }
-
-        /// <summary>
         /// Find write handler for type.
         /// </summary>
         /// <param name="type">Type.</param>
@@ -294,10 +277,10 @@ namespace Apache.Ignite.Core.Impl.Binary
             if (TypeIds.TryGetValue(type, out res))
                 return res;
 
-            if (type.IsEnum)
+            if (BinaryUtils.IsIgniteEnum(type))
                 return BinaryUtils.TypeEnum;
 
-            if (type.IsArray && type.GetElementType().IsEnum)
+            if (type.IsArray && BinaryUtils.IsIgniteEnum(type.GetElementType()))
                 return BinaryUtils.TypeArrayEnum;
 
             return BinaryUtils.TypeObject;
@@ -545,7 +528,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             var binEnum = obj;
 
-            ctx.Stream.WriteByte(BinaryUtils.TypeEnum);
+            ctx.Stream.WriteByte(BinaryUtils.TypeBinaryEnum);
 
             ctx.WriteInt(binEnum.TypeId);
             ctx.WriteInt(binEnum.EnumValue);

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 a2783ba..2ac617e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -143,6 +143,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** Type: enum array. */
         public const byte TypeArrayEnum = 29;
 
+        /** Type: binary enum. */
+        public const byte TypeBinaryEnum = 38;
+
         /** Type: native job holder. */
         public const byte TypeNativeJobHolder = 77;
 
@@ -1778,6 +1781,22 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Determines whether specified type is Ignite-compatible enum (value fits into 4 bytes).
+        /// </summary>
+        public static bool IsIgniteEnum(Type type)
+        {
+            Debug.Assert(type != null);
+
+            if (!type.IsEnum)
+                return false;
+
+            var enumType = Enum.GetUnderlyingType(type);
+
+            return enumType == typeof(int) || enumType == typeof(byte) || enumType == typeof(sbyte) 
+                || enumType == typeof(short) || enumType == typeof(ushort) || enumType == typeof(uint);
+        }
+
+        /// <summary>
         /// Creates and instance from the type name in reader.
         /// </summary>
         private static T CreateInstance<T>(BinaryReader reader)

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 56774d4..a5fed48 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
@@ -1468,7 +1468,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             {
                 _metas = new Dictionary<int, BinaryType>(1)
                 {
-                    {desc.TypeId, new BinaryType(desc, fields)}
+                    {desc.TypeId, new BinaryType(desc, _marsh, fields)}
                 };
             }
             else
@@ -1478,7 +1478,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                 if (_metas.TryGetValue(desc.TypeId, out meta))
                     meta.UpdateFields(fields);
                 else
-                    _metas[desc.TypeId] = new BinaryType(desc, fields);
+                    _metas[desc.TypeId] = new BinaryType(desc, _marsh, fields);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index ea2964a..8f12acf 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -97,13 +97,13 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             if (typeCfgs != null)
                 foreach (BinaryTypeConfiguration typeCfg in typeCfgs)
-                    AddUserType(cfg, typeCfg, typeResolver);
+                    AddUserType(typeCfg, typeResolver);
 
             var typeNames = _cfg.Types;
 
             if (typeNames != null)
                 foreach (string typeName in typeNames)
-                    AddUserType(cfg, new BinaryTypeConfiguration(typeName), typeResolver);
+                    AddUserType(new BinaryTypeConfiguration(typeName), typeResolver);
         }
 
         /// <summary>
@@ -289,14 +289,16 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         /// <param name="typeId">Type ID.</param>
         /// <returns>Metadata or null.</returns>
-        public IBinaryType GetBinaryType(int typeId)
+        public BinaryType GetBinaryType(int typeId)
         {
             if (Ignite != null)
             {
-                IBinaryType meta = Ignite.BinaryProcessor.GetBinaryType(typeId);
+                var meta = Ignite.BinaryProcessor.GetBinaryType(typeId);
 
                 if (meta != null)
+                {
                     return meta;
+                }
             }
 
             return BinaryType.Empty;
@@ -314,7 +316,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             if (Ignite != null)
             {
-                ICollection<BinaryType> metas = new[] {new BinaryType(desc)};
+                ICollection<BinaryType> metas = new[] {new BinaryType(desc, this)};
                 Ignite.BinaryProcessor.PutBinaryTypes(metas);
             }
         }
@@ -337,7 +339,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                         IDictionary<int, BinaryTypeHolder> metas0 =
                             new Dictionary<int, BinaryTypeHolder>(_metas);
 
-                        holder = new BinaryTypeHolder(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName, desc.IsEnum);
+                        holder = new BinaryTypeHolder(desc.TypeId, desc.TypeName, desc.AffinityKeyFieldName, 
+                            desc.IsEnum, this);
 
                         metas0[desc.TypeId] = holder;
 
@@ -366,16 +369,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             foreach (var meta in newMetas)
             {
-                var mergeInfo = new Dictionary<int, Tuple<string, BinaryField>>(meta.GetFieldsMap().Count);
-
-                foreach (var fieldMeta in meta.GetFieldsMap())
-                {
-                    int fieldId = BinaryUtils.FieldId(meta.TypeId, fieldMeta.Key, null, null);
-
-                    mergeInfo[fieldId] = new Tuple<string, BinaryField>(fieldMeta.Key, fieldMeta.Value);
-                }
-
-                _metas[meta.TypeId].Merge(mergeInfo);
+                _metas[meta.TypeId].Merge(meta);
             }
         }
 
@@ -391,7 +385,9 @@ namespace Apache.Ignite.Core.Impl.Binary
             BinaryFullTypeDescriptor desc;
 
             if (!_typeToDesc.TryGetValue(type, out desc) || !desc.IsRegistered)
+            {
                 desc = RegisterType(type, desc);
+            }
 
             return desc;
         }
@@ -405,10 +401,14 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             BinaryFullTypeDescriptor desc;
 
-            return _typeNameToDesc.TryGetValue(typeName, out desc)
-                ? (IBinaryTypeDescriptor) desc
-                : new BinarySurrogateTypeDescriptor(_cfg,
-                    GetTypeId(typeName, _cfg.IdMapper), typeName);
+            if (_typeNameToDesc.TryGetValue(typeName, out desc))
+            {
+                return desc;
+            }
+
+            var typeId = GetTypeId(typeName, _cfg.IdMapper);
+
+            return GetDescriptor(true, typeId, typeName: typeName);
         }
 
         /// <summary>
@@ -416,18 +416,18 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         /// <param name="userType">User type flag.</param>
         /// <param name="typeId">Type id.</param>
-        /// <param name="requiresType">
-        /// If set to true, resulting descriptor must have Type property populated.
+        /// <param name="requiresType">If set to true, resulting descriptor must have Type property populated.
         /// <para />
         /// When working in binary mode, we don't need Type. And there is no Type at all in some cases.
         /// So we should not attempt to call BinaryProcessor right away.
         /// Only when we really deserialize the value, requiresType is set to true
-        /// and we attempt to resolve the type by all means.
-        /// </param>
+        /// and we attempt to resolve the type by all means.</param>
+        /// <param name="typeName">Known type name.</param>
         /// <returns>
         /// Descriptor.
         /// </returns>
-        public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false)
+        public IBinaryTypeDescriptor GetDescriptor(bool userType, int typeId, bool requiresType = false, 
+            string typeName = null)
         {
             BinaryFullTypeDescriptor desc;
 
@@ -442,7 +442,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             if (requiresType && _ignite != null)
             {
                 // Check marshaller context for dynamically registered type.
-                var typeName = _ignite.BinaryProcessor.GetTypeName(typeId);
+                typeName = typeName ?? _ignite.BinaryProcessor.GetTypeName(typeId);
 
                 if (typeName != null)
                 {
@@ -460,15 +460,16 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             if (meta != BinaryType.Empty)
             {
-                desc = new BinaryFullTypeDescriptor(null, meta.TypeId, meta.TypeName, true, null, null, null, false,
-                    meta.AffinityKeyFieldName, meta.IsEnum);
-
-                _idToDesc.GetOrAdd(typeKey, _ => desc);
+                var typeCfg = new BinaryTypeConfiguration(meta.TypeName)
+                {
+                    IsEnum = meta.IsEnum,
+                    AffinityKeyFieldName = meta.AffinityKeyFieldName
+                };
 
-                return desc;
+                return AddUserType(typeCfg, new TypeResolver());
             }
 
-            return new BinarySurrogateTypeDescriptor(_cfg, typeId, null);
+            return new BinarySurrogateTypeDescriptor(_cfg, typeId, typeName);
         }
 
         /// <summary>
@@ -507,7 +508,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
             desc = desc == null
                 ? new BinaryFullTypeDescriptor(type, typeId, typeName, true, _cfg.NameMapper,
-                    _cfg.IdMapper, ser, false, null, type.IsEnum, registered)
+                    _cfg.IdMapper, ser, false, null, BinaryUtils.IsIgniteEnum(type), registered)
                 : new BinaryFullTypeDescriptor(desc, type, ser, registered);
 
             if (RegistrationDisabled)
@@ -540,11 +541,10 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Add user type.
         /// </summary>
-        /// <param name="cfg">The binary configuration.</param>
         /// <param name="typeCfg">Type configuration.</param>
         /// <param name="typeResolver">The type resolver.</param>
         /// <exception cref="BinaryObjectException"></exception>
-        private void AddUserType(BinaryConfiguration cfg, BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
+        private BinaryFullTypeDescriptor AddUserType(BinaryTypeConfiguration typeCfg, TypeResolver typeResolver)
         {
             // Get converter/mapper/serializer.
             IBinaryNameMapper nameMapper = typeCfg.NameMapper ?? _cfg.NameMapper ?? GetDefaultNameMapper();
@@ -560,23 +560,23 @@ namespace Apache.Ignite.Core.Impl.Binary
             {
                 ValidateUserType(type);
 
-                if (typeCfg.IsEnum != type.IsEnum)
+                if (typeCfg.IsEnum != BinaryUtils.IsIgniteEnum(type))
                 {
                     throw new BinaryObjectException(
                         string.Format(
                             "Invalid IsEnum flag in binary type configuration. " +
-                            "Configuration value: IsEnum={0}, actual type: IsEnum={1}",
-                            typeCfg.IsEnum, type.IsEnum));
+                            "Configuration value: IsEnum={0}, actual type: IsEnum={1}, type={2}",
+                            typeCfg.IsEnum, type.IsEnum, type));
                 }
 
                 // Type is found.
                 var typeName = GetTypeName(type, nameMapper);
                 int typeId = GetTypeId(typeName, idMapper);
                 var affKeyFld = typeCfg.AffinityKeyFieldName ?? GetAffinityKeyFieldNameFromAttribute(type);
-                var serializer = GetSerializer(cfg, typeCfg, type, typeId, nameMapper, idMapper, _log);
+                var serializer = GetSerializer(_cfg, typeCfg, type, typeId, nameMapper, idMapper, _log);
 
-                AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer,
-                    affKeyFld, type.IsEnum);
+                return AddType(type, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, serializer,
+                    affKeyFld, BinaryUtils.IsIgniteEnum(type));
             }
             else
             {
@@ -585,7 +585,7 @@ namespace Apache.Ignite.Core.Impl.Binary
 
                 int typeId = GetTypeId(typeName, idMapper);
 
-                AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null,
+                return AddType(null, typeId, typeName, true, keepDeserialized, nameMapper, idMapper, null,
                     typeCfg.AffinityKeyFieldName, typeCfg.IsEnum);
             }
         }
@@ -653,7 +653,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <param name="serializer">Serializer.</param>
         /// <param name="affKeyFieldName">Affinity key field name.</param>
         /// <param name="isEnum">Enum flag.</param>
-        private void AddType(Type type, int typeId, string typeName, bool userType,
+        private BinaryFullTypeDescriptor AddType(Type type, int typeId, string typeName, bool userType,
             bool keepDeserialized, IBinaryNameMapper nameMapper, IBinaryIdMapper idMapper,
             IBinarySerializerInternal serializer, string affKeyFieldName, bool isEnum)
         {
@@ -685,6 +685,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                 _typeNameToDesc.GetOrAdd(typeName, x => descriptor);
 
             _idToDesc.GetOrAdd(typeKey, _ => descriptor);
+
+            return descriptor;
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
index 837c28a..db54ce7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
@@ -17,9 +17,11 @@
 
 namespace Apache.Ignite.Core.Impl.Binary.Metadata
 {
+    using System;
     using System.Collections.Generic;
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Common;
 
@@ -30,7 +32,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
     {
         /** Empty metadata. */
         public static readonly BinaryType Empty =
-            new BinaryType(BinaryUtils.TypeObject, BinaryTypeNames.TypeNameObject, null, null, false);
+            new BinaryType(BinaryUtils.TypeObject, BinaryTypeNames.TypeNameObject, null, null, false, null, null);
 
         /** Empty dictionary. */
         private static readonly IDictionary<string, BinaryField> EmptyDict = new Dictionary<string, BinaryField>();
@@ -44,6 +46,12 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /** Fields. */
         private readonly IDictionary<string, BinaryField> _fields;
 
+        /** Enum values. */
+        private readonly IDictionary<string, int> _enumNameToValue;
+
+        /** Enum names. */
+        private readonly IDictionary<int, string> _enumValueToName;
+
         /** Enum flag. */
         private readonly bool _isEnum;
 
@@ -59,6 +67,9 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /** Type descriptor. */
         private readonly IBinaryTypeDescriptor _descriptor;
 
+        /** Marshaller. */
+        private readonly Marshaller _marshaller;
+
         /// <summary>
         /// Initializes the <see cref="BinaryType"/> class.
         /// </summary>
@@ -117,7 +128,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// Initializes a new instance of the <see cref="BinaryType" /> class.
         /// </summary>
         /// <param name="reader">The reader.</param>
-        public BinaryType(IBinaryRawReader reader)
+        public BinaryType(BinaryReader reader)
         {
             _typeId = reader.ReadInt();
             _typeName = reader.ReadString();
@@ -136,15 +147,34 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             }
             
             _isEnum = reader.ReadBoolean();
+
+            if (_isEnum)
+            {
+                var count = reader.ReadInt();
+
+                _enumNameToValue = new Dictionary<string, int>(count);
+
+                for (var i = 0; i < count; i++)
+                {
+                    _enumNameToValue[reader.ReadString()] = reader.ReadInt();
+                }
+
+                _enumValueToName = _enumNameToValue.ToDictionary(x => x.Value, x => x.Key);
+            }
+
+            _marshaller = reader.Marshaller;
         }
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="BinaryType"/> class.
+        /// Initializes a new instance of the <see cref="BinaryType" /> class.
         /// </summary>
         /// <param name="desc">Descriptor.</param>
+        /// <param name="marshaller">Marshaller.</param>
         /// <param name="fields">Fields.</param>
-        public BinaryType(IBinaryTypeDescriptor desc, IDictionary<string, BinaryField> fields = null) 
-            : this (desc.TypeId, desc.TypeName, fields, desc.AffinityKeyFieldName, desc.IsEnum)
+        public BinaryType(IBinaryTypeDescriptor desc, Marshaller marshaller, 
+            IDictionary<string, BinaryField> fields = null) 
+            : this (desc.TypeId, desc.TypeName, fields, desc.AffinityKeyFieldName, desc.IsEnum, 
+                  GetEnumValues(desc), marshaller)
         {
             _descriptor = desc;
         }
@@ -157,14 +187,24 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// <param name="fields">Fields.</param>
         /// <param name="affKeyFieldName">Affinity key field name.</param>
         /// <param name="isEnum">Enum flag.</param>
+        /// <param name="enumValues">Enum values.</param>
+        /// <param name="marshaller">Marshaller.</param>
         public BinaryType(int typeId, string typeName, IDictionary<string, BinaryField> fields,
-            string affKeyFieldName, bool isEnum)
+            string affKeyFieldName, bool isEnum, IDictionary<string, int> enumValues, Marshaller marshaller)
         {
             _typeId = typeId;
             _typeName = typeName;
             _affinityKeyFieldName = affKeyFieldName;
             _fields = fields;
             _isEnum = isEnum;
+            _enumNameToValue = enumValues;
+
+            if (_enumNameToValue != null)
+            {
+                _enumValueToName = _enumNameToValue.ToDictionary(x => x.Value, x => x.Key);
+            }
+
+            _marshaller = marshaller;
         }
 
         /// <summary>
@@ -232,6 +272,27 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             get { return _isEnum; }
         }
 
+        /** <inheritdoc /> */
+        public IEnumerable<IBinaryObject> GetEnumValues()
+        {
+            if (!_isEnum)
+            {
+                throw new NotSupportedException(
+                    "IBinaryObject.Value is only supported for enums. " +
+                    "Check IBinaryObject.GetBinaryType().IsEnum property before accessing Value.");
+            }
+
+            if (_marshaller == null)
+            {
+                yield break;
+            }
+
+            foreach (var pair in _enumValueToName)
+            {
+                yield return new BinaryEnum(_typeId, pair.Key, _marshaller);
+            }
+        }
+
         /// <summary>
         /// Gets the descriptor.
         /// </summary>
@@ -250,6 +311,14 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         }
 
         /// <summary>
+        /// Gets the enum values map.
+        /// </summary>
+        public IDictionary<string, int> EnumValuesMap
+        {
+            get { return _enumNameToValue; }
+        }
+
+        /// <summary>
         /// Updates the fields.
         /// </summary>
         public void UpdateFields(IDictionary<string, BinaryField> fields)
@@ -262,5 +331,103 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             foreach (var field in fields)
                 _fields[field.Key] = field.Value;
         }
+
+        /// <summary>
+        /// Gets the enum value by name.
+        /// </summary>
+        public int? GetEnumValue(string valueName)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(valueName, "valueName");
+
+            if (!_isEnum)
+            {
+                throw new NotSupportedException("Can't get enum value for a non-enum type: " + _typeName);
+            }
+
+            int res;
+
+            return _enumNameToValue != null && _enumNameToValue.TryGetValue(valueName, out res) ? res : (int?) null;
+        }
+
+        /// <summary>
+        /// Gets the name of the enum value.
+        /// </summary>
+        public string GetEnumName(int value)
+        {
+            if (!_isEnum)
+            {
+                throw new NotSupportedException("Can't get enum value for a non-enum type: " + _typeName);
+            }
+
+            string res;
+
+            return _enumValueToName != null && _enumValueToName.TryGetValue(value, out res) ? res : null;
+        }
+
+        /// <summary>
+        /// Gets the enum values.
+        /// </summary>
+        private static IDictionary<string, int> GetEnumValues(IBinaryTypeDescriptor desc)
+        {
+            if (desc == null || desc.Type == null || !desc.IsEnum)
+            {
+                return null;
+            }
+
+            var enumType = desc.Type;
+
+            var values = Enum.GetValues(enumType);
+            var res = new Dictionary<string, int>(values.Length);
+
+            var underlyingType = Enum.GetUnderlyingType(enumType);
+
+            foreach (var value in values)
+            {
+                var name = Enum.GetName(enumType, value);
+                Debug.Assert(name != null);
+
+                res[name] = GetEnumValueAsInt(underlyingType, value);
+            }
+
+            return res;
+        }
+
+        /// <summary>
+        /// Gets the enum value as int.
+        /// </summary>
+        private static int GetEnumValueAsInt(Type underlyingType, object value)
+        {
+            if (underlyingType == typeof(int))
+            {
+                return (int) value;
+            }
+
+            if (underlyingType == typeof(byte))
+            {
+                return (byte) value;
+            }
+
+            if (underlyingType == typeof(sbyte))
+            {
+                return (sbyte) value;
+            }
+
+            if (underlyingType == typeof(short))
+            {
+                return (short) value;
+            }
+
+            if (underlyingType == typeof(ushort))
+            {
+                return (ushort) value;
+            }
+
+            if (underlyingType == typeof(uint))
+            {
+                return unchecked((int) (uint) value);
+            }
+
+            throw new BinaryObjectException("Unexpected enum underlying type: " + underlyingType);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
index cdbc687..7e1e970 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
@@ -17,8 +17,8 @@
 
 namespace Apache.Ignite.Core.Impl.Binary.Metadata
 {
-    using System;
     using System.Collections.Generic;
+    using System.Diagnostics;
 
     /// <summary>
     /// Metadata for particular type.
@@ -37,6 +37,9 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /** Enum flag. */
         private readonly bool _isEnum;
 
+        /** Marshaller. */
+        private readonly Marshaller _marshaller;
+
         /** Collection of know field IDs. */
         private volatile HashSet<int> _ids;
 
@@ -46,7 +49,6 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /** Saved flag (set if type metadata was saved at least once). */
         private volatile bool _saved;
 
-
         /// <summary>
         /// Constructor.
         /// </summary>
@@ -54,12 +56,15 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// <param name="typeName">Type name.</param>
         /// <param name="affKeyFieldName">Affinity key field name.</param>
         /// <param name="isEnum">Enum flag.</param>
-        public BinaryTypeHolder(int typeId, string typeName, string affKeyFieldName, bool isEnum)
+        /// <param name="marshaller">The marshaller.</param>
+        public BinaryTypeHolder(int typeId, string typeName, string affKeyFieldName, bool isEnum,
+            Marshaller marshaller)
         {
             _typeId = typeId;
             _typeName = typeName;
             _affKeyFieldName = affKeyFieldName;
             _isEnum = isEnum;
+            _marshaller = marshaller;
         }
 
         /// <summary>
@@ -100,13 +105,19 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// <summary>
         /// Merge newly sent field metadatas into existing ones.
         /// </summary>
-        /// <param name="newMap">New field metadatas map.</param>
-        public void Merge(IDictionary<int, Tuple<string, BinaryField>> newMap)
+        /// <param name="meta">Binary type to merge.</param>
+        public void Merge(BinaryType meta)
         {
+            Debug.Assert(meta != null);
+            
             _saved = true;
 
-            if (newMap == null || newMap.Count == 0)
+            var fieldsMap = meta.GetFieldsMap();
+
+            if (fieldsMap.Count == 0)
+            {
                 return;
+            }
 
             lock (this)
             {
@@ -118,20 +129,27 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
 
                 IDictionary<string, BinaryField> newFields = meta0 != null 
                     ? new Dictionary<string, BinaryField>(meta0.GetFieldsMap()) 
-                    : new Dictionary<string, BinaryField>(newMap.Count);
+                    : new Dictionary<string, BinaryField>(fieldsMap.Count);
 
                 // 2. Add new fields.
-                foreach (var newEntry in newMap)
+                foreach (var fieldMeta in fieldsMap)
                 {
-                    if (!newIds.Contains(newEntry.Key))
-                        newIds.Add(newEntry.Key);
+                    int fieldId = BinaryUtils.FieldId(meta.TypeId, fieldMeta.Key, null, null);
 
-                    if (!newFields.ContainsKey(newEntry.Value.Item1))
-                        newFields[newEntry.Value.Item1] = newEntry.Value.Item2;
+                    if (!newIds.Contains(fieldId))
+                    {
+                        newIds.Add(fieldId);
+                    }
+
+                    if (!newFields.ContainsKey(fieldMeta.Key))
+                    {
+                        newFields[fieldMeta.Key] = fieldMeta.Value;
+                    }
                 }
 
                 // 3. Assign new meta. Order is important here: meta must be assigned before field IDs.
-                _meta = new BinaryType(_typeId, _typeName, newFields, _affKeyFieldName, _isEnum);
+                _meta = new BinaryType(_typeId, _typeName, newFields, _affKeyFieldName, _isEnum, 
+                    meta.EnumValuesMap, _marshaller);
                 _ids = newIds;
             }
         }


[02/11] ignite git commit: .NET: Remove dead code from exe project

Posted by sb...@apache.org.
.NET: Remove dead code from exe project


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

Branch: refs/heads/ignite-5075
Commit: d911848d4240af5ea17e79b2312132c2047b3071
Parents: cfc7436
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri May 26 11:43:57 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri May 26 11:43:57 2017 +0300

----------------------------------------------------------------------
 .../dotnet/Apache.Ignite/Apache.Ignite.csproj   |  1 -
 .../Apache.Ignite/Service/ServiceDescription.cs | 32 --------------------
 2 files changed, 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d911848d/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
index 13379f5..3e8f83e 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
@@ -52,7 +52,6 @@
     <Compile Include="Service\IgniteService.cs">
       <SubType>Component</SubType>
     </Compile>
-    <Compile Include="Service\ServiceDescription.cs" />
     <Compile Include="Service\IgniteServiceInstaller.cs">
       <SubType>Component</SubType>
     </Compile>

http://git-wip-us.apache.org/repos/asf/ignite/blob/d911848d/modules/platforms/dotnet/Apache.Ignite/Service/ServiceDescription.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite/Service/ServiceDescription.cs b/modules/platforms/dotnet/Apache.Ignite/Service/ServiceDescription.cs
deleted file mode 100644
index a81a737..0000000
--- a/modules/platforms/dotnet/Apache.Ignite/Service/ServiceDescription.cs
+++ /dev/null
@@ -1,32 +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.Service
-{
-    using System;
-    using System.Runtime.InteropServices;
-
-    /// <summary>
-    /// Service description structure.
-    /// </summary>
-    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
-    public struct ServiceDescription
-    {
-        /** Pointer to description. */
-        public IntPtr desc;
-    }
-}
\ No newline at end of file


[08/11] ignite git commit: IGNITE-4575: Improved binary enums support. This closes #1968.

Posted by sb...@apache.org.
IGNITE-4575: Improved binary enums support. This closes #1968.


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

Branch: refs/heads/ignite-5075
Commit: b5c7b6f5ed81a9cee242e3abb052c29ec571a9a9
Parents: d38ca8b
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Fri May 26 14:07:06 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri May 26 14:07:06 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/IgniteBinary.java    |  23 ++-
 .../org/apache/ignite/binary/BinaryObject.java  |   8 +
 .../org/apache/ignite/binary/BinaryType.java    |   5 +
 .../ignite/binary/BinaryTypeConfiguration.java  |  26 +++
 .../binary/BinaryCachingMetadataHandler.java    |   5 +
 .../internal/binary/BinaryClassDescriptor.java  |   4 +-
 .../ignite/internal/binary/BinaryContext.java   |  60 +++++--
 .../internal/binary/BinaryEnumObjectImpl.java   |  30 +++-
 .../internal/binary/BinaryFieldAccessor.java    |  10 ++
 .../ignite/internal/binary/BinaryMetadata.java  |  93 +++++++++-
 .../internal/binary/BinaryMetadataHandler.java  |   9 +
 .../binary/BinaryNoopMetadataHandler.java       |   5 +
 .../internal/binary/BinaryObjectExImpl.java     |   5 +
 .../internal/binary/BinaryReaderExImpl.java     |  18 ++
 .../ignite/internal/binary/BinaryTypeImpl.java  |  15 ++
 .../ignite/internal/binary/BinaryTypeProxy.java |   6 +
 .../ignite/internal/binary/BinaryUtils.java     | 104 ++++++++++-
 .../internal/binary/BinaryWriterExImpl.java     |  18 +-
 .../internal/binary/GridBinaryMarshaller.java   |   3 +
 .../binary/builder/BinaryBuilderSerializer.java |  10 +-
 .../binary/builder/BinaryObjectBuilderImpl.java |   2 +-
 .../binary/CacheObjectBinaryProcessor.java      |  21 ++-
 .../binary/CacheObjectBinaryProcessorImpl.java  |  72 +++++++-
 .../cache/binary/IgniteBinaryImpl.java          |  26 +++
 .../processors/cacheobject/NoOpBinary.java      |  12 ++
 .../platform/PlatformContextImpl.java           |  29 ++-
 .../binary/PlatformBinaryProcessor.java         |  25 +++
 .../internal/binary/BinaryEnumsSelfTest.java    | 146 ++++++++++++++-
 .../binary/TestCachingMetadataHandler.java      |   5 +
 .../platform/PlatformComputeEchoTask.java       |  13 ++
 .../Binary/BinaryBuilderSelfTest.cs             |  88 +++++++--
 .../Compute/ComputeApiTest.cs                   |  25 +++
 .../Binary/BinaryTypeConfiguration.cs           |   3 +-
 .../dotnet/Apache.Ignite.Core/Binary/IBinary.cs |  24 +++
 .../Apache.Ignite.Core/Binary/IBinaryObject.cs  |   8 +
 .../Apache.Ignite.Core/Binary/IBinaryType.cs    |   6 +
 .../Apache.Ignite.Core/Impl/Binary/Binary.cs    |  67 ++++++-
 .../Impl/Binary/BinaryEnum.cs                   |  11 +-
 .../Impl/Binary/BinaryObject.cs                 |  13 +-
 .../Impl/Binary/BinaryProcessor.cs              |  65 ++++++-
 .../Impl/Binary/BinaryReader.cs                 |  10 +-
 .../Impl/Binary/BinarySystemHandlers.cs         |  25 +--
 .../Impl/Binary/BinaryUtils.cs                  |  19 ++
 .../Impl/Binary/BinaryWriter.cs                 |   4 +-
 .../Impl/Binary/Marshaller.cs                   |  88 ++++-----
 .../Impl/Binary/Metadata/BinaryType.cs          | 179 ++++++++++++++++++-
 .../Impl/Binary/Metadata/BinaryTypeHolder.cs    |  44 +++--
 47 files changed, 1338 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
index 1d1c0c3..3550ff5 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
 import org.apache.ignite.binary.BinaryObjectBuilder;
@@ -374,11 +375,29 @@ public interface IgniteBinary {
     public Collection<BinaryType> types() throws BinaryObjectException;
 
     /**
-     * Create enum object.
+     * Create enum object using value.
      *
      * @param typeName Type name.
      * @param ord Ordinal.
      * @return Enum object.
      */
-    public BinaryObject buildEnum(String typeName, int ord);
+    public BinaryObject buildEnum(String typeName, int ord) throws BinaryObjectException;
+
+    /**
+     * Create enum object using name.
+     *
+     * @param typeName Type name.
+     * @param name Name.
+     * @return Enum object.
+     */
+    public BinaryObject buildEnum(String typeName, String name) throws BinaryObjectException;
+
+    /**
+     * Register enum type.
+     *
+     * @param typeName Type name.
+     * @param vals Mapping of enum constant names to ordinals.
+     * @return Binary type for registered enum.
+     */
+    public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws BinaryObjectException;
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
index 3d99757..b9e653f 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryObject.java
@@ -162,4 +162,12 @@ public interface BinaryObject extends Serializable, Cloneable {
      * @throws BinaryObjectException If object is not enum.
      */
     public int enumOrdinal() throws BinaryObjectException;
+
+    /**
+     * Get name for this enum object. Use {@link BinaryType#isEnum()} to check if object is of enum type.
+     *
+     * @return Name.
+     * @throws BinaryObjectException If object is not enum.
+     */
+    public String enumName() throws BinaryObjectException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
index f184a8c..f4bc206 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryType.java
@@ -79,4 +79,9 @@ public interface BinaryType {
      * @return {@code True} if type is enum.
      */
     public boolean isEnum();
+
+    /**
+     * @return Collection of enum values.
+     */
+    public Collection<BinaryObject> enumValues();
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
index 54b853c..2d00bd2 100644
--- a/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/binary/BinaryTypeConfiguration.java
@@ -23,6 +23,9 @@ import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 /**
  * Defines configuration properties for a specific binary type. Providing per-type
  * configuration is optional, as it is generally enough, and also optional, to provide global binary
@@ -46,6 +49,9 @@ public class BinaryTypeConfiguration {
     /** Enum flag. */
     private boolean isEnum;
 
+    /** Enum names to ordinals mapping. */
+    private Map<String, Integer> enumValues;
+
     /**
      * Constructor.
      */
@@ -64,6 +70,7 @@ public class BinaryTypeConfiguration {
         idMapper = other.idMapper;
         isEnum = other.isEnum;
         serializer = other.serializer;
+        enumValues = other.enumValues != null ? new LinkedHashMap<>(other.enumValues) : null;
         typeName = other.typeName;
     }
 
@@ -179,6 +186,25 @@ public class BinaryTypeConfiguration {
         return this;
     }
 
+    /**
+     * Set enum ordinal to names mapping.
+     *
+     * @param values Map of enum name to ordinal.
+     * @return {@code this} for chaining.
+     */
+    public BinaryTypeConfiguration setEnumValues(@Nullable Map<String, Integer> values) {
+        this.enumValues = values;
+
+        return this;
+    }
+
+    /**
+     * @return Enum name to ordinal mapping
+     */
+    @Nullable public Map<String, Integer> getEnumValues() {
+        return enumValues;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(BinaryTypeConfiguration.class, this, super.toString());

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
index 24a393d..27cccaa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryCachingMetadataHandler.java
@@ -69,6 +69,11 @@ public class BinaryCachingMetadataHandler implements BinaryMetadataHandler {
     }
 
     /** {@inheritDoc} */
+    @Override public synchronized BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+        return ((BinaryTypeImpl)metas.get(typeId)).metadata();
+    }
+
+    /** {@inheritDoc} */
     @Override public synchronized BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
         BinaryTypeImpl type = (BinaryTypeImpl) metas.get(typeId);
         return type.metadata().hasSchema(schemaId) ? type : null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 7194f49..adfdcfc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -758,7 +758,7 @@ public class BinaryClassDescriptor {
                                 BinarySchema newSchema = collector.schema();
 
                                 BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(),
-                                    affKeyFieldName, Collections.singleton(newSchema), false);
+                                    affKeyFieldName, Collections.singleton(newSchema), false, null);
 
                                 ctx.updateMetadata(typeId, meta);
 
@@ -779,7 +779,7 @@ public class BinaryClassDescriptor {
                 if (userType && !stableSchemaPublished) {
                     // Update meta before write object with new schema
                     BinaryMetadata meta = new BinaryMetadata(typeId, typeName, stableFieldsMeta,
-                        affKeyFieldName, Collections.singleton(stableSchema), false);
+                        affKeyFieldName, Collections.singleton(stableSchema), false, null);
 
                     ctx.updateMetadata(typeId, meta);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index da46496..70bc2f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -461,17 +461,17 @@ public class BinaryContext {
 
                     for (String clsName0 : classesInPackage(pkgName))
                         descs.add(clsName0, mapper, serializer, identity, affFields.get(clsName0),
-                            typeCfg.isEnum(), true);
+                            typeCfg.isEnum(), typeCfg.getEnumValues(), true);
                 }
                 else
                     descs.add(clsName, mapper, serializer, identity, affFields.get(clsName),
-                        typeCfg.isEnum(), false);
+                        typeCfg.isEnum(), typeCfg.getEnumValues(), false);
             }
         }
 
         for (TypeDescriptor desc : descs.descriptors())
             registerUserType(desc.clsName, desc.mapper, desc.serializer, desc.identity, desc.affKeyFieldName,
-                desc.isEnum);
+                desc.isEnum, desc.enumMap);
 
         BinaryInternalMapper globalMapper = resolveMapper(globalNameMapper, globalIdMapper);
 
@@ -649,7 +649,8 @@ public class BinaryContext {
                         desc0.typeName(),
                         desc0.fieldsMeta(),
                         desc0.affFieldKeyName(),
-                        schemas, desc0.isEnum());
+                        schemas, desc0.isEnum(),
+                        cls.isEnum() ? enumMap(cls) : null);
 
                     metaHnd.addMeta(desc0.typeId(), meta.wrap(this));
 
@@ -799,8 +800,8 @@ public class BinaryContext {
         );
 
         if (!deserialize)
-            metaHnd.addMeta(typeId,
-                new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null, desc.isEnum()).wrap(this));
+            metaHnd.addMeta(typeId, new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, null,
+                desc.isEnum(), cls.isEnum() ? enumMap(cls) : null).wrap(this));
 
         descByCls.put(cls, desc);
 
@@ -1095,6 +1096,7 @@ public class BinaryContext {
      * @param identity Type identity.
      * @param affKeyFieldName Affinity key field name.
      * @param isEnum If enum.
+     * @param enumMap Enum name to ordinal mapping.
      * @throws BinaryObjectException In case of error.
      */
     @SuppressWarnings("ErrorNotRethrown")
@@ -1103,8 +1105,8 @@ public class BinaryContext {
         @Nullable BinarySerializer serializer,
         @Nullable BinaryIdentityResolver identity,
         @Nullable String affKeyFieldName,
-        boolean isEnum)
-        throws BinaryObjectException {
+        boolean isEnum,
+        @Nullable Map<String, Integer> enumMap) throws BinaryObjectException {
         assert mapper != null;
 
         Class<?> cls = null;
@@ -1172,7 +1174,8 @@ public class BinaryContext {
             predefinedTypes.put(id, desc);
         }
 
-        metaHnd.addMeta(id, new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, null, isEnum).wrap(this));
+        metaHnd.addMeta(id,
+            new BinaryMetadata(id, typeName, fieldsMeta, affKeyFieldName, null, isEnum, enumMap).wrap(this));
     }
 
     /**
@@ -1222,6 +1225,16 @@ public class BinaryContext {
     }
 
     /**
+     *
+     * @param typeId Type ID
+     * @return Meta data.
+     * @throws BinaryObjectException In case of error.
+     */
+    @Nullable public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+        return metaHnd != null ? metaHnd.metadata0(typeId) : null;
+    }
+
+    /**
      * @param typeId Type ID.
      * @param schemaId Schema ID.
      * @return Meta data.
@@ -1351,6 +1364,24 @@ public class BinaryContext {
     }
 
     /**
+     *
+     * @param cls Class
+     * @return Enum name to ordinal mapping.
+     */
+    private static Map<String, Integer> enumMap(Class<?> cls) {
+        assert cls.isEnum();
+
+        Object[] enumVals = cls.getEnumConstants();
+
+        Map<String, Integer> enumMap = new LinkedHashMap<>(enumVals.length);
+
+        for (Object enumVal : enumVals)
+            enumMap.put(((Enum)enumVal).name(), ((Enum)enumVal).ordinal());
+
+        return enumMap;
+    }
+
+    /**
      * Type descriptors.
      */
     private static class TypeDescriptors {
@@ -1366,6 +1397,7 @@ public class BinaryContext {
          * @param identity Key hashing mode.
          * @param affKeyFieldName Affinity key field name.
          * @param isEnum Enum flag.
+         * @param enumMap Enum constants mapping.
          * @param canOverride Whether this descriptor can be override.
          * @throws BinaryObjectException If failed.
          */
@@ -1375,6 +1407,7 @@ public class BinaryContext {
             BinaryIdentityResolver identity,
             String affKeyFieldName,
             boolean isEnum,
+            Map<String, Integer> enumMap,
             boolean canOverride)
             throws BinaryObjectException {
             TypeDescriptor desc = new TypeDescriptor(clsName,
@@ -1383,6 +1416,7 @@ public class BinaryContext {
                 identity,
                 affKeyFieldName,
                 isEnum,
+                enumMap,
                 canOverride);
 
             TypeDescriptor oldDesc = descs.get(clsName);
@@ -1425,6 +1459,9 @@ public class BinaryContext {
         /** Enum flag. */
         private boolean isEnum;
 
+        /** Enum ordinal to name mapping. */
+        private Map<String, Integer> enumMap;
+
         /** Whether this descriptor can be override. */
         private boolean canOverride;
 
@@ -1436,17 +1473,19 @@ public class BinaryContext {
          * @param identity Key hashing mode.
          * @param affKeyFieldName Affinity key field name.
          * @param isEnum Enum type.
+         * @param enumMap Mapping of enum names to ordinals.
          * @param canOverride Whether this descriptor can be override.
          */
         private TypeDescriptor(String clsName, BinaryInternalMapper mapper,
             BinarySerializer serializer, BinaryIdentityResolver identity, String affKeyFieldName, boolean isEnum,
-            boolean canOverride) {
+            Map<String, Integer> enumMap, boolean canOverride) {
             this.clsName = clsName;
             this.mapper = mapper;
             this.serializer = serializer;
             this.identity = identity;
             this.affKeyFieldName = affKeyFieldName;
             this.isEnum = isEnum;
+            this.enumMap = enumMap;
             this.canOverride = canOverride;
         }
 
@@ -1465,6 +1504,7 @@ public class BinaryContext {
                 identity = other.identity;
                 affKeyFieldName = other.affKeyFieldName;
                 isEnum = other.isEnum;
+                enumMap = other.enumMap;
                 canOverride = other.canOverride;
             }
             else if (!other.canOverride)

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
index cc9941e..f889e45 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryEnumObjectImpl.java
@@ -97,9 +97,18 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac
     public BinaryEnumObjectImpl(BinaryContext ctx, byte[] arr) {
         assert ctx != null;
         assert arr != null;
-        assert arr[0] == GridBinaryMarshaller.ENUM;
 
-        valBytes = arr;
+        if (arr[0] == GridBinaryMarshaller.ENUM)
+            valBytes = arr;
+        else {
+            assert arr[0] == GridBinaryMarshaller.BINARY_ENUM;
+
+            valBytes = new byte[arr.length];
+
+            valBytes[0] = GridBinaryMarshaller.ENUM;
+
+            U.arrayCopy(arr, 1, valBytes, 1, arr.length - 1);
+        }
 
         this.ctx = ctx;
 
@@ -187,6 +196,23 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac
     }
 
     /** {@inheritDoc} */
+    @Override public String enumName() throws BinaryObjectException {
+        BinaryMetadata metadata = ctx.metadata0(typeId);
+
+        if (metadata == null)
+            throw new BinaryObjectException("Failed to get metadata for enum [typeId=" +
+                typeId + ", typeName='" + clsName + "', ordinal=" + ord + "]");
+
+        String name = metadata.getEnumNameByOrdinal(ord);
+
+        if (name == null)
+            throw new BinaryObjectException("Unable to resolve enum constant name [typeId=" +
+                typeId + ", typeName='" + metadata.typeName() + "', ordinal=" + ord + "]");
+
+        return name;
+    }
+
+    /** {@inheritDoc} */
     @Override public int hashCode() {
         return 31 * typeId + ord;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
index f7d35f0..567bee1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
@@ -647,6 +647,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case BINARY_ENUM:
+                    writer.doWriteBinaryEnum((BinaryEnumObjectImpl)val);
+
+                    break;
+
                 case ENUM_ARR:
                     writer.writeEnumArrayField((Object[])val);
 
@@ -863,6 +868,11 @@ public abstract class BinaryFieldAccessor {
 
                     break;
 
+                case BINARY_ENUM:
+                    val = reader.readBinaryEnum(id);
+
+                    break;
+
                 case BINARY:
                 case OBJECT:
                     val = reader.readObject(id);

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
index a8b7fcb..ead00b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadata.java
@@ -27,9 +27,12 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
+
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
@@ -41,6 +44,9 @@ public class BinaryMetadata implements Externalizable {
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** */
+    private static final int VERSION = 1;
+
     /** Type ID. */
     @GridToStringInclude(sensitive = true)
     private int typeId;
@@ -67,6 +73,12 @@ public class BinaryMetadata implements Externalizable {
     /** Whether this is enum type. */
     private boolean isEnum;
 
+    /** Enum name to ordinal mapping. */
+    private Map<String, Integer> nameToOrdinal;
+
+    /** Enum ordinal to name mapping. */
+    private Map<Integer, String> ordinalToName;
+
     /**
      * For {@link Externalizable}.
      */
@@ -83,9 +95,11 @@ public class BinaryMetadata implements Externalizable {
      * @param affKeyFieldName Affinity key field name.
      * @param schemas Schemas.
      * @param isEnum Enum flag.
+     * @param enumMap Enum name to ordinal mapping.
      */
     public BinaryMetadata(int typeId, String typeName, @Nullable Map<String, BinaryFieldMetadata> fields,
-        @Nullable String affKeyFieldName, @Nullable Collection<BinarySchema> schemas, boolean isEnum) {
+        @Nullable String affKeyFieldName, @Nullable Collection<BinarySchema> schemas, boolean isEnum,
+        @Nullable Map<String, Integer> enumMap) {
         assert typeName != null;
 
         this.typeId = typeId;
@@ -104,6 +118,15 @@ public class BinaryMetadata implements Externalizable {
             schemaIds = Collections.emptySet();
 
         this.isEnum = isEnum;
+
+        if (enumMap != null) {
+            this.nameToOrdinal = new LinkedHashMap<>(enumMap);
+
+            this.ordinalToName = new LinkedHashMap<>(enumMap.size());
+
+            for (Map.Entry<String, Integer> e: nameToOrdinal.entrySet())
+                this.ordinalToName.put(e.getValue(), e.getKey());
+        }
     }
 
     /**
@@ -197,6 +220,7 @@ public class BinaryMetadata implements Externalizable {
      * @exception IOException Includes any I/O exceptions that may occur.
      */
     public void writeTo(DataOutput out) throws IOException {
+        out.writeByte(VERSION);
         out.writeInt(typeId);
 
         U.writeString(out, typeName);
@@ -224,6 +248,18 @@ public class BinaryMetadata implements Externalizable {
         }
 
         out.writeBoolean(isEnum);
+
+        if (isEnum) {
+            Map<String, Integer> map = enumMap();
+
+            out.writeInt(map.size());
+
+            for (Map.Entry<String, Integer> e : map.entrySet()) {
+                U.writeString(out, e.getKey());
+
+                out.writeInt(e.getValue());
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -242,6 +278,8 @@ public class BinaryMetadata implements Externalizable {
      * @exception IOException if I/O errors occur.
      */
     public void readFrom(DataInput in) throws IOException {
+        in.readByte(); //skip version
+
         typeId = in.readInt();
         typeName = U.readString(in);
 
@@ -285,6 +323,59 @@ public class BinaryMetadata implements Externalizable {
         }
 
         isEnum = in.readBoolean();
+
+        if (isEnum) {
+            int size = in.readInt();
+
+            if (size >= 0) {
+                ordinalToName = new LinkedHashMap<>(size);
+                nameToOrdinal = new LinkedHashMap<>(size);
+
+                for (int idx = 0; idx < size; idx++) {
+                    String name = U.readString(in);
+
+                    int ord = in.readInt();
+
+                    ordinalToName.put(ord, name);
+                    nameToOrdinal.put(name, ord);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets enum constant name given its ordinal value.
+     *
+     * @param ord Enum constant ordinal value.
+     * @return Enum constant name.
+     */
+    public String getEnumNameByOrdinal(int ord) {
+        if (ordinalToName == null)
+            return null;
+
+        return ordinalToName.get(ord);
+    }
+
+    /**
+     * Gets enum constant ordinal value given its name.
+     *
+     * @param name Enum constant name.
+     * @return Enum constant ordinal value.
+     */
+    public Integer getEnumOrdinalByName(String name) {
+        assert name != null;
+
+        return nameToOrdinal.get(name);
+    }
+
+    /**
+     * @return Name to ordinal mapping.
+     */
+    public Map<String, Integer> enumMap() {
+        if (nameToOrdinal == null)
+            return Collections.emptyMap();
+
+        return nameToOrdinal;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
index 748a283..e565338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMetadataHandler.java
@@ -43,6 +43,15 @@ public interface BinaryMetadataHandler {
     public BinaryType metadata(int typeId) throws BinaryObjectException;
 
     /**
+     * Gets unwrapped meta data for provided type ID.
+     *
+     * @param typeId Type ID.
+     * @return Metadata.
+     * @throws BinaryObjectException In case of error.
+     */
+    public BinaryMetadata metadata0(int typeId) throws BinaryObjectException;
+
+    /**
      * Gets metadata for provided type ID and schema ID.
      *
      * @param typeId Type ID.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
index 770d9c8..39c942a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryNoopMetadataHandler.java
@@ -52,6 +52,11 @@ public class BinaryNoopMetadataHandler implements BinaryMetadataHandler {
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+        return null;
+    }
+
+    /** {@inheritDoc} */
     @Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
index ae9a160..b5e066b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryObjectExImpl.java
@@ -77,6 +77,11 @@ public abstract class BinaryObjectExImpl implements BinaryObjectEx {
         throw new BinaryObjectException("Object is not enum.");
     }
 
+    /** {@inheritDoc} */
+    @Override public String enumName() throws BinaryObjectException {
+        throw new BinaryObjectException("Object is not enum.");
+    }
+
     /**
      * Get offset of data begin.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index c8ca803..2b7964c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -41,6 +41,7 @@ import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_ENUM;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BINARY_OBJ;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN;
 import static org.apache.ignite.internal.binary.GridBinaryMarshaller.BOOLEAN_ARR;
@@ -1426,6 +1427,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /**
      * @param fieldId Field ID.
+     * @return Binary Enum
+     * @throws BinaryObjectException If failed.
+     */
+    @Nullable BinaryEnumObjectImpl readBinaryEnum(int fieldId) throws BinaryObjectException {
+        return findFieldById(fieldId) ? BinaryUtils.doReadBinaryEnum(in, ctx) : null;
+    }
+
+    /**
+     * @param fieldId Field ID.
      * @param cls Class.
      * @return Value.
      * @throws BinaryObjectException In case of error.
@@ -1930,6 +1940,14 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
                 break;
 
+            case BINARY_ENUM:
+                obj = BinaryUtils.doReadBinaryEnum(in, ctx);
+
+                if (!GridBinaryMarshaller.KEEP_BINARIES.get())
+                    obj = ((BinaryObject)obj).deserialize();
+
+                break;
+
             case CLASS:
                 obj = BinaryUtils.doReadClass(in, ctx, ldr);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
index 132702c..fac1ff9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeImpl.java
@@ -17,9 +17,12 @@
 
 package org.apache.ignite.internal.binary;
 
+import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryType;
 
+import java.util.ArrayList;
 import java.util.Collection;
+
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
@@ -80,6 +83,18 @@ public class BinaryTypeImpl implements BinaryType {
         return meta.isEnum();
     }
 
+    /** {@inheritDoc} */
+    @Override public Collection<BinaryObject> enumValues() {
+        Collection<Integer> ordinals = meta.enumMap().values();
+
+        ArrayList<BinaryObject> enumValues = new ArrayList<>(ordinals.size());
+
+        for (Integer ord: ordinals)
+            enumValues.add(new BinaryEnumObjectImpl(ctx, typeId(), typeName(), ord));
+
+        return enumValues;
+    }
+
     /**
      * @return Context.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
index df9901e..3a51050 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryTypeProxy.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.binary;
 
 import org.apache.ignite.binary.BinaryField;
+import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryType;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -92,6 +93,11 @@ public class BinaryTypeProxy implements BinaryType {
         return target().isEnum();
     }
 
+    /** {@inheritDoc} */
+    @Override public Collection<BinaryObject> enumValues() {
+        return target().enumValues();
+    }
+
     /**
      * @return Target type.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index f36c137..00b15da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -266,6 +266,7 @@ public class BinaryUtils {
         FIELD_TYPE_NAMES[GridBinaryMarshaller.TIME_ARR] = "Time[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.OBJ_ARR] = "Object[]";
         FIELD_TYPE_NAMES[GridBinaryMarshaller.ENUM_ARR] = "Enum[]";
+        FIELD_TYPE_NAMES[GridBinaryMarshaller.BINARY_ENUM] = "Enum";
 
         if (wrapTrees()) {
             CLS_TO_WRITE_REPLACER.put(TreeMap.class, new BinaryTreeMapWriteReplacer());
@@ -975,6 +976,14 @@ public class BinaryUtils {
 
             boolean changed = false;
 
+            Map<String, Integer> mergedEnumMap = null;
+
+            if (!F.isEmpty(newMeta.enumMap())) {
+                mergedEnumMap = mergeEnumValues(oldMeta.typeName(), oldMeta.enumMap(), newMeta.enumMap());
+
+                changed = mergedEnumMap.size() > oldMeta.enumMap().size();
+            }
+
             for (Map.Entry<String, BinaryFieldMetadata> newField : newFields.entrySet()) {
                 BinaryFieldMetadata oldFieldMeta = mergedFields.put(newField.getKey(), newField.getValue());
 
@@ -1005,7 +1014,7 @@ public class BinaryUtils {
 
             // Return either old meta if no changes detected, or new merged meta.
             return changed ? new BinaryMetadata(oldMeta.typeId(), oldMeta.typeName(), mergedFields,
-                oldMeta.affinityKeyFieldName(), mergedSchemas, oldMeta.isEnum()) : oldMeta;
+                oldMeta.affinityKeyFieldName(), mergedSchemas, oldMeta.isEnum(), mergedEnumMap) : oldMeta;
         }
     }
 
@@ -1106,6 +1115,8 @@ public class BinaryUtils {
             return BinaryWriteMode.MAP;
         else if (cls.isEnum())
             return BinaryWriteMode.ENUM;
+        else if (cls == BinaryEnumObjectImpl.class)
+            return BinaryWriteMode.BINARY_ENUM;
         else if (cls == Class.class)
             return BinaryWriteMode.CLASS;
         else if (Proxy.class.isAssignableFrom(cls))
@@ -1627,6 +1638,17 @@ public class BinaryUtils {
      *
      * @param in Input stream.
      * @param ctx Binary context.
+     * @return Enum.
+     */
+    public static BinaryEnumObjectImpl doReadBinaryEnum(BinaryInputStream in, BinaryContext ctx) {
+        return doReadBinaryEnum(in, ctx, doReadEnumType(in));
+    }
+
+    /**
+     * Read binary enum.
+     *
+     * @param in Input stream.
+     * @param ctx Binary context.
      * @param type Plain type.
      * @return Enum.
      */
@@ -1903,6 +1925,7 @@ public class BinaryUtils {
                 return doReadBinaryObject(in, ctx, detach);
 
             case GridBinaryMarshaller.ENUM:
+            case GridBinaryMarshaller.BINARY_ENUM:
                 return doReadBinaryEnum(in, ctx, doReadEnumType(in));
 
             case GridBinaryMarshaller.ENUM_ARR:
@@ -2356,6 +2379,85 @@ public class BinaryUtils {
     }
 
     /**
+     * Checks enum values mapping.
+     *
+     * @param typeName Name of the type.
+     * @param enumValues Enum name to ordinal mapping.
+     * @throws BinaryObjectException
+     */
+    public static void validateEnumValues(String typeName, @Nullable Map<String, Integer> enumValues)
+            throws BinaryObjectException {
+
+        if (enumValues == null)
+            return;
+
+        Map<Integer, String> tmpMap = new LinkedHashMap<>(enumValues.size());
+        for (Map.Entry<String, Integer> e: enumValues.entrySet()) {
+
+            String prevName = tmpMap.put(e.getValue(), e.getKey());
+
+            if (prevName != null)
+                throw new BinaryObjectException("Conflicting enum values. Name '" + e.getKey() +
+                        "' uses ordinal value (" + e.getValue() +
+                        ") that is also used for name '" + prevName +
+                        "' [typeName='" + typeName + "']");
+        }
+    }
+
+    /**
+     * Merges enum value mappings and checks for conflicts.
+     *
+     * Possible conflicts:
+     * - same name is used for different ordinal values.
+     * - ordinal value is used more than once.
+     *
+     * @param typeName Name of the type.
+     * @param oldValues Old enum value mapping.
+     * @param newValues New enum value mapping.
+     * @throws BinaryObjectException in case of name or value conflict.
+     */
+    public static Map<String, Integer> mergeEnumValues(String typeName,
+            @Nullable Map<String, Integer> oldValues,
+            Map<String, Integer> newValues)
+            throws BinaryObjectException {
+
+        assert newValues != null;
+
+        int size = (oldValues != null) ? oldValues.size() + newValues.size() : newValues.size();
+
+        Map<Integer, String> revMap = new LinkedHashMap<>(size);
+        Map<String, Integer> mergedMap = new LinkedHashMap<>(size);
+
+        if (oldValues != null) {
+            //assuming that old values were validated earlier once.
+            for (Map.Entry<String, Integer> e : oldValues.entrySet()) {
+                revMap.put(e.getValue(), e.getKey());
+                mergedMap.put(e.getKey(), e.getValue());
+            }
+        }
+
+        for (Map.Entry<String, Integer> e: newValues.entrySet()) {
+            String prevName = revMap.put(e.getValue(), e.getKey());
+
+            if (prevName != null && !prevName.equals(e.getKey()))
+                throw new BinaryObjectException("Conflicting enum values. Name '" + e.getKey() +
+                        "' uses ordinal value (" + e.getValue() +
+                        ") that is also used for name '" + prevName +
+                        "' [typeName='" + typeName + "']");
+
+            Integer prevVal = mergedMap.put(e.getKey(), e.getValue());
+
+            if (prevVal != null && !prevVal.equals(e.getValue()))
+                throw new BinaryObjectException("Conflicting enum values. Value (" + e.getValue() +
+                        ") has name '" + e.getKey() +
+                        "' that is also used for value '" + prevVal +
+                        "' [typeName='" + typeName + "']");
+        }
+
+        return mergedMap;
+    }
+
+    /**
      * Enum type.
      */
     private static class EnumType {

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
index 7efe4b3..f2ba779 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryWriterExImpl.java
@@ -820,15 +820,23 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
 
         int typeId = val.typeId();
 
-        out.unsafeEnsure(1 + 4);
+        if (typeId != GridBinaryMarshaller.UNREGISTERED_TYPE_ID) {
+            out.unsafeEnsure(1 + 4 + 4);
 
-        out.unsafeWriteByte(GridBinaryMarshaller.ENUM);
-        out.unsafeWriteInt(typeId);
+            out.unsafeWriteByte(GridBinaryMarshaller.BINARY_ENUM);
+            out.unsafeWriteInt(typeId);
+            out.unsafeWriteInt(val.enumOrdinal());
+        }
+        else {
+            out.unsafeEnsure(1 + 4);
+
+            out.unsafeWriteByte(GridBinaryMarshaller.BINARY_ENUM);
+            out.unsafeWriteInt(typeId);
 
-        if (typeId == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
             doWriteString(val.className());
 
-        out.writeInt(val.enumOrdinal());
+            out.writeInt(val.enumOrdinal());
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
index d4b0ff4..291c638 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
@@ -153,6 +153,9 @@ public class GridBinaryMarshaller {
     /** Time array. */
     public static final byte TIME_ARR = 37;
 
+    /** Binary enum */
+    public static final byte BINARY_ENUM = 38;
+
     /** */
     public static final byte NULL = (byte)101;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
index 6974176..b1a8da9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.binary.builder;
 
 import java.util.Collection;
 import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.internal.binary.BinaryMetadata;
@@ -115,7 +116,14 @@ class BinaryBuilderSerializer {
             int typeId = writer.context().typeId(clsName);
             String typeName = writer.context().userTypeName(clsName);
 
-            BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true);
+            Object[] enumVals = val.getClass().getEnumConstants();
+
+            Map<String, Integer> enumMap = new LinkedHashMap<>(enumVals.length);
+
+            for (Object enumVal : enumVals)
+                enumMap.put(((Enum)enumVal).name(), ((Enum)enumVal).ordinal());
+
+            BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true, enumMap);
 
             writer.context().updateMetadata(typeId, meta);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
index 02e06fd..d6cd5ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
@@ -350,7 +350,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
                 BinarySchema curSchema = writer.currentSchema();
 
                 ctx.updateMetadata(typeId, new BinaryMetadata(typeId, typeName, fieldsMeta,
-                    ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false));
+                    ctx.affinityKeyFieldName(typeId), Collections.singleton(curSchema), false, null));
 
                 schemaReg.addSchema(curSchema.schemaId(), curSchema);
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
index 1564ff3..4d285ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessor.java
@@ -59,10 +59,12 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor {
      * @param affKeyFieldName Affinity key field name.
      * @param fieldTypeIds Fields map.
      * @param isEnum Enum flag.
+     * @param enumMap Enum name to ordinal mapping.
      * @throws IgniteException In case of error.
      */
     public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName,
-        Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum) throws IgniteException;
+        Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum, @Nullable Map<String, Integer> enumMap)
+        throws IgniteException;
 
     /**
      * @param typeId Type ID.
@@ -102,6 +104,23 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor {
     public BinaryObject buildEnum(String typeName, int ord) throws IgniteException;
 
     /**
+     * @param typeName Type name.
+     * @param name Name.
+     * @return Enum object.
+     * @throws IgniteException If failed.
+     */
+    public BinaryObject buildEnum(String typeName, String name) throws IgniteException;
+
+    /**
+     * Register enum type
+     *
+     * @param typeName Type name.
+     * @param vals Mapping of enum constant names to ordinals.
+     * @return Binary Type for registered enum.
+     */
+    public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws IgniteException;
+
+    /**
      * @return Binaries interface.
      * @throws IgniteException If failed.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index 636d149..14947e9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -71,6 +71,7 @@ import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T1;
 import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteClosure;
@@ -170,6 +171,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
                     return CacheObjectBinaryProcessorImpl.this.metadata(typeId);
                 }
 
+                @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+                    return CacheObjectBinaryProcessorImpl.this.metadata0(typeId);
+                }
+
                 @Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
                     return CacheObjectBinaryProcessorImpl.this.metadata(typeId, schemaId);
                 }
@@ -207,6 +212,9 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
                                     c.isEnum()
                                 )
                             );
+
+                            if (c.isEnum())
+                                BinaryUtils.validateEnumValues(c.getTypeName(), c.getEnumValues());
                         }
 
                         map.put("typeCfgs", typeCfgsMap);
@@ -399,8 +407,10 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
 
     /** {@inheritDoc} */
     @Override public void updateMetadata(int typeId, String typeName, @Nullable String affKeyFieldName,
-        Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum) throws BinaryObjectException {
-        BinaryMetadata meta = new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null, isEnum);
+        Map<String, BinaryFieldMetadata> fieldTypeIds, boolean isEnum, @Nullable Map<String, Integer> enumMap)
+        throws BinaryObjectException {
+        BinaryMetadata meta = new BinaryMetadata(typeId, typeName, fieldTypeIds, affKeyFieldName, null, isEnum,
+            enumMap);
 
         binaryCtx.updateMetadata(typeId, meta);
     }
@@ -433,6 +443,17 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
 
     /** {@inheritDoc} */
     @Nullable @Override public BinaryType metadata(final int typeId) {
+        BinaryMetadata meta = metadata0(typeId);
+
+        return meta != null ? meta.wrap(binaryCtx) : null;
+    }
+
+    /**
+     * @param typeId Type ID.
+     * @return Meta data.
+     * @throws IgniteException In case of error.
+     */
+    @Nullable public BinaryMetadata metadata0(final int typeId) {
         BinaryMetadataHolder holder = metadataLocCache.get(typeId);
 
         if (holder == null) {
@@ -466,7 +487,7 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
                 }
             }
 
-            return holder.metadata().wrap(binaryCtx);
+            return holder.metadata();
         }
         else
             return null;
@@ -547,17 +568,58 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
     }
 
     /** {@inheritDoc} */
-    @Override public BinaryObject buildEnum(String typeName, int ord) throws IgniteException {
+    @Override public BinaryObject buildEnum(String typeName, int ord) throws BinaryObjectException {
+        A.notNullOrEmpty(typeName, "enum type name");
+
         int typeId = binaryCtx.typeId(typeName);
 
         typeName = binaryCtx.userTypeName(typeName);
 
-        updateMetadata(typeId, typeName, null, null, true);
+        updateMetadata(typeId, typeName, null, null, true, null);
 
         return new BinaryEnumObjectImpl(binaryCtx, typeId, null, ord);
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, String name) throws BinaryObjectException {
+        A.notNullOrEmpty(typeName, "enum type name");
+        A.notNullOrEmpty(name, "enum name");
+
+        int typeId = binaryCtx.typeId(typeName);
+
+        BinaryMetadata metadata = metadata0(typeId);
+
+        if (metadata == null)
+            throw new BinaryObjectException("Failed to get metadata for type [typeId=" +
+                    typeId + ", typeName='" + typeName + "']");
+
+        Integer ordinal = metadata.getEnumOrdinalByName(name);
+
+        typeName = binaryCtx.userTypeName(typeName);
+
+        if (ordinal == null)
+            throw new BinaryObjectException("Failed to resolve enum ordinal by name [typeId=" +
+                    typeId + ", typeName='" + typeName + "', name='" + name + "']");
+
+        return new BinaryEnumObjectImpl(binaryCtx, typeId, null, ordinal);
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType registerEnum(String typeName, Map<String, Integer> vals) throws BinaryObjectException {
+        A.notNullOrEmpty(typeName, "enum type name");
+
+        int typeId = binaryCtx.typeId(typeName);
+
+        typeName = binaryCtx.userTypeName(typeName);
+
+        BinaryUtils.validateEnumValues(typeName, vals);
+
+        updateMetadata(typeId, typeName, null, null, true, vals);
+
+        return binaryCtx.metadata(typeId);
+    }
+
+    /** {@inheritDoc} */
     @Override public IgniteBinary binary() throws IgniteException {
         return binaries;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
index 1a2d0a9..e88819b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/IgniteBinaryImpl.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.internal.processors.cache.binary;
 
 import java.util.Collection;
+import java.util.Map;
+
 import org.apache.ignite.IgniteBinary;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
@@ -155,6 +157,30 @@ public class IgniteBinaryImpl implements IgniteBinary {
         }
     }
 
+    /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, String name) {
+        guard();
+
+        try {
+            return proc.buildEnum(typeName, name);
+        }
+        finally {
+            unguard();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public BinaryType registerEnum(String typeName, Map<String, Integer> vals) {
+        guard();
+
+        try {
+            return proc.registerEnum(typeName, vals);
+        }
+        finally {
+            unguard();
+        }
+    }
+
     /**
      * @return Binary processor.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
index c1c8fed..32c3be6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
@@ -17,6 +17,8 @@
 package org.apache.ignite.internal.processors.cacheobject;
 
 import java.util.Collection;
+import java.util.Map;
+
 import org.apache.ignite.IgniteBinary;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryObjectBuilder;
@@ -74,6 +76,16 @@ public class NoOpBinary implements IgniteBinary {
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, String name) {
+        throw unsupported();
+    }
+
+    /** {@inheritDoc} */
+    @Override public BinaryType registerEnum(String typeName, Map<String, Integer> vals) {
+        throw unsupported();
+    }
+
+    /** {@inheritDoc} */
     private BinaryObjectException unsupported() {
         return new BinaryObjectException("Binary marshaller is not configured.");
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
index 090f382..f115a9c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformContextImpl.java
@@ -82,6 +82,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -371,8 +372,19 @@ public class PlatformContextImpl implements PlatformContext {
                             }
                         });
 
+                    Map<String, Integer> enumMap = null;
+
                     boolean isEnum = reader.readBoolean();
 
+                    if (isEnum) {
+                        int size = reader.readInt();
+
+                        enumMap = new LinkedHashMap<>(size);
+
+                        for (int idx = 0; idx < size; idx++)
+                            enumMap.put(reader.readString(), reader.readInt());
+                    }
+
                     // Read schemas
                     int schemaCnt = reader.readInt();
 
@@ -393,7 +405,7 @@ public class PlatformContextImpl implements PlatformContext {
                         }
                     }
 
-                    return new BinaryMetadata(typeId, typeName, fields, affKey, schemas, isEnum);
+                    return new BinaryMetadata(typeId, typeName, fields, affKey, schemas, isEnum, enumMap);
                 }
             }
         );
@@ -474,7 +486,20 @@ public class PlatformContextImpl implements PlatformContext {
                 writer.writeInt(e.getValue().fieldId());
             }
 
-            writer.writeBoolean(meta.isEnum());
+            if (meta.isEnum()) {
+                writer.writeBoolean(true);
+
+                Map<String, Integer> enumMap = meta0.enumMap();
+
+                writer.writeInt(enumMap.size());
+
+                for (Map.Entry<String, Integer> e: enumMap.entrySet()) {
+                    writer.writeString(e.getKey());
+                    writer.writeInt(e.getValue());
+                }
+            }
+            else
+                writer.writeBoolean(false);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
index 8d95ac8..be43848 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/binary/PlatformBinaryProcessor.java
@@ -19,12 +19,16 @@ package org.apache.ignite.internal.processors.platform.binary;
 
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.binary.BinaryType;
 import org.apache.ignite.internal.MarshallerPlatformIds;
 import org.apache.ignite.internal.binary.BinaryRawReaderEx;
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
 import org.apache.ignite.internal.processors.platform.PlatformAbstractTarget;
 import org.apache.ignite.internal.processors.platform.PlatformContext;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Platform binary processor.
  */
@@ -47,6 +51,9 @@ public class PlatformBinaryProcessor extends PlatformAbstractTarget {
     /** */
     private static final int OP_GET_TYPE = 6;
 
+    /** */
+    private static final int OP_REGISTER_ENUM = 7;
+
     /**
      * Constructor.
      *
@@ -122,6 +129,24 @@ public class PlatformBinaryProcessor extends PlatformAbstractTarget {
                 break;
             }
 
+            case OP_REGISTER_ENUM: {
+                String name = reader.readString();
+
+                int cnt = reader.readInt();
+
+                Map<String, Integer> vals = new HashMap<>(cnt);
+
+                for (int i = 0; i< cnt; i++) {
+                    vals.put(reader.readString(), reader.readInt());
+                }
+
+                BinaryType binaryType = platformCtx.kernalContext().grid().binary().registerEnum(name, vals);
+
+                platformCtx.writeMetadata(writer, binaryType.typeId());
+
+                break;
+            }
+
             default:
                 super.processInStreamOutStream(type, reader, writer);
                 break;

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
index a223022..fd26d4a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryEnumsSelfTest.java
@@ -19,10 +19,14 @@ package org.apache.ignite.internal.binary;
 
 import java.io.Serializable;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryTypeConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.configuration.BinaryConfiguration;
@@ -31,7 +35,9 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
 /**
@@ -42,6 +48,9 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
     /** Cache name. */
     private static String CACHE_NAME = "cache";
 
+    /** Name of the node that starts with bad config */
+    private static String WRONG_CONF_NODE_NAME = "WrongConfNode";
+
     /** Whether to register types or not. */
     private boolean register;
 
@@ -81,8 +90,20 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
             BinaryConfiguration bCfg = new BinaryConfiguration();
 
             BinaryTypeConfiguration enumCfg = new BinaryTypeConfiguration(EnumType.class.getName());
+
             enumCfg.setEnum(true);
 
+            if (igniteInstanceName.equals(WRONG_CONF_NODE_NAME))
+                enumCfg.setEnumValues(F.asMap(EnumType.ONE.name(),
+                        EnumType.ONE.ordinal(),
+                        EnumType.TWO.name(),
+                        EnumType.ONE.ordinal()));
+            else
+                enumCfg.setEnumValues(F.asMap(EnumType.ONE.name(),
+                        EnumType.ONE.ordinal(),
+                        EnumType.TWO.name(),
+                        EnumType.TWO.ordinal()));
+
             bCfg.setTypeConfigurations(Arrays.asList(enumCfg, new BinaryTypeConfiguration(EnumHolder.class.getName())));
 
             cfg.setBinaryConfiguration(bCfg);
@@ -317,11 +338,14 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
     public void checkSimpleBuilder(boolean registered) throws Exception {
         startUp(registered);
 
-        BinaryObject binary = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+        BinaryObject binaryOne = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+        BinaryObject binaryTwo = node1.binary().buildEnum(EnumType.class.getName(), EnumType.TWO.ordinal());
 
-        cacheBinary1.put(1, binary);
+        cacheBinary1.put(EnumType.ONE.ordinal(), binaryOne);
+        cacheBinary1.put(EnumType.TWO.ordinal(), binaryTwo);
 
-        validateSimple(1, EnumType.ONE, registered);
+        validateSimple(EnumType.ONE.ordinal(), EnumType.ONE, registered);
+        validateSimple(EnumType.TWO.ordinal(), EnumType.TWO, registered);
     }
 
     /**
@@ -409,6 +433,112 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Checks ability to get a collection of binary enums from binary type
+     *
+     * @throws Exception
+     */
+    public void testBinaryTypeEnumValues() throws Exception {
+        startUp(false);
+
+        defineEnum();
+
+        BinaryObject binaryOne = node1.binary().buildEnum(EnumType.class.getName(), EnumType.ONE.ordinal());
+        BinaryObject binaryTwo = node1.binary().buildEnum(EnumType.class.getName(), EnumType.TWO.name());
+
+        Collection<BinaryObject> vals = binaryOne.type().enumValues();
+
+        assertEqualsCollections(F.asList(binaryOne, binaryTwo), vals);
+    }
+
+    /**
+     * Checks the enum configuration validation during start up
+     *
+     * @throws Exception
+     */
+    public void testEnumWrongBinaryConfig() throws Exception {
+        this.register = true;
+
+        GridTestUtils.assertThrows(log, new Callable<Object> (){
+            @Override public Object call() throws Exception {
+                startGrid(WRONG_CONF_NODE_NAME);
+
+                return null;
+            }
+        }, IgniteCheckedException.class, "Conflicting enum values");
+    }
+
+    /**
+     * Checks the enum validation during type registration
+     *
+     * @throws Exception
+     */
+    public void testEnumValidation() throws Exception {
+        startUp(false);
+
+        GridTestUtils.assertThrows(log, new Callable<Object> (){
+
+            @Override public Object call() throws Exception {
+
+                node1.binary().registerEnum("invalidEnumType1",
+                    F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+                    EnumType.TWO.name(), EnumType.ONE.ordinal()));
+
+                return null;
+            }
+        }, BinaryObjectException.class, "Conflicting enum values");
+    }
+
+    /**
+     * Checks the enum merge
+     *
+     * @throws Exception
+     */
+    public void testEnumMerge() throws Exception {
+        startUp(false);
+
+        final String enumName = "mergedEnum";
+
+        node1.binary().registerEnum(enumName,
+                F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal()));
+
+        GridTestUtils.assertThrows(log, new Callable<Object> (){
+
+            @Override public Object call() throws Exception {
+
+                node2.binary().registerEnum(enumName,
+                        F.asMap(EnumType.TWO.name(), EnumType.ONE.ordinal()));
+
+                return null;
+            }
+        }, BinaryObjectException.class, "Conflicting enum values. Name ");
+
+        GridTestUtils.assertThrows(log, new Callable<Object> (){
+            @Override public Object call() throws Exception {
+
+                node2.binary().registerEnum(enumName,
+                        F.asMap(EnumType.ONE.name(), EnumType.TWO.ordinal()));
+
+                return null;
+            }
+        }, BinaryObjectException.class, "Conflicting enum values. Value ");
+
+        node2.binary().registerEnum(enumName,
+                F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+                        EnumType.TWO.name(), EnumType.TWO.ordinal()));
+
+        Collection<BinaryObject> vals = node1.binary().type(enumName).enumValues();
+        BinaryObject[] values = vals.toArray(new BinaryObject[vals.size()]);
+
+        assertEquals(2, values.length);
+
+        assertEquals(EnumType.ONE.ordinal(), values[0].enumOrdinal());
+        assertEquals(EnumType.TWO.ordinal(), values[1].enumOrdinal());
+
+        assertEquals(EnumType.ONE.name(), values[0].enumName());
+        assertEquals(EnumType.TWO.name(), values[1].enumName());
+    }
+
+    /**
      * Validate simple array.
      *
      * @param registered Registered flag.
@@ -472,6 +602,16 @@ public class BinaryEnumsSelfTest extends GridCommonAbstractTest {
         assertEquals(node2.binary().typeId(EnumType.class.getName()), obj.type().typeId());
 
         assertEquals(val.ordinal(), obj.enumOrdinal());
+
+        if (register)
+            assertEquals(val.name(), obj.enumName());
+    }
+
+    /** Register enum */
+    private void defineEnum() {
+        node1.binary().registerEnum(EnumType.class.getName(),
+                F.asMap(EnumType.ONE.name(), EnumType.ONE.ordinal(),
+                        EnumType.TWO.name(), EnumType.TWO.ordinal()));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
index 704c8f3..77cbffe 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/TestCachingMetadataHandler.java
@@ -44,6 +44,11 @@ public class TestCachingMetadataHandler implements BinaryMetadataHandler {
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryMetadata metadata0(int typeId) throws BinaryObjectException {
+        return null;
+    }
+
+    /** {@inheritDoc} */
     @Override public BinaryType metadata(int typeId, int schemaId) throws BinaryObjectException {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
index a5a35c1..984cf62 100644
--- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
+++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
@@ -110,6 +110,9 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object>
     /** Type: ignite uuid. */
     private static final int TYPE_IGNITE_UUID = 22;
 
+    /** Type: binary enum. */
+    private static final int TYPE_BINARY_ENUM = 23;
+
     /** Default cache name. */
     public static final String DEFAULT_CACHE_NAME = "default";
 
@@ -228,6 +231,16 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object>
                 case TYPE_IGNITE_UUID:
                     return ignite.cache(DEFAULT_CACHE_NAME).get(TYPE_IGNITE_UUID);
 
+                case TYPE_BINARY_ENUM: {
+                    Map<String, Integer> values = new HashMap<>(2);
+                    values.put("JavaFoo", 1);
+                    values.put("JavaBar", 2);
+
+                    ignite.binary().registerEnum("JavaDynEnum", values);
+
+                    return ignite.binary().buildEnum("JavaDynEnum", "JavaFoo");
+                }
+
                 default:
                     throw new IgniteException("Unknown type: " + type);
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 a7794c6..61f90a3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs
@@ -1140,6 +1140,9 @@ namespace Apache.Ignite.Core.Tests.Binary
             Assert.AreEqual(new[] { TestEnum.Two }, obj.FEnumArr);
         }
 
+        /// <summary>
+        /// Tests the enum metadata.
+        /// </summary>
         [Test]
         public void TestEnumMeta()
         {
@@ -1148,14 +1151,21 @@ namespace Apache.Ignite.Core.Tests.Binary
             // 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(_marsh.GetDescriptor(typeof(TestEnumRegistered)).TypeId, binEnum.GetBinaryType().TypeId);
             Assert.AreEqual(0, binEnum.EnumValue);
+            Assert.AreEqual("One", binEnum.EnumName);
 
             var meta = binEnum.GetBinaryType();
 
             Assert.IsTrue(meta.IsEnum);
-            Assert.AreEqual(GetTypeName(typeof (TestEnumRegistered)), meta.TypeName);
+            Assert.AreEqual(GetTypeName(typeof(TestEnumRegistered)), meta.TypeName);
             Assert.AreEqual(0, meta.Fields.Count);
+
+            var enumValues = meta.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+            Assert.AreEqual(0, enumValues[0].EnumValue);
+            Assert.AreEqual("One", enumValues[0].EnumName);
+            Assert.AreEqual(1, enumValues[1].EnumValue);
+            Assert.AreEqual("Two", enumValues[1].EnumName);
         }
 
         /// <summary>
@@ -1653,26 +1663,30 @@ namespace Apache.Ignite.Core.Tests.Binary
         {
             var binary = _grid.GetBinary();
 
-            int val = (int)TestEnumRegistered.Two;
+            var enumVal = TestEnumRegistered.Two;
+            var intVal = (int) enumVal;
             var typeName = GetTypeName(typeof(TestEnumRegistered));
             var typeId = BinaryUtils.GetStringHashCode(typeName);
 
             var binEnums = new[]
             {
-                binary.BuildEnum(typeof (TestEnumRegistered), val),
-                binary.BuildEnum(typeName, val)
+                binary.BuildEnum(typeof (TestEnumRegistered), intVal),
+                binary.BuildEnum(typeName, intVal),
+                binary.BuildEnum(typeof (TestEnumRegistered), enumVal.ToString()),
+                binary.BuildEnum(typeName, enumVal.ToString())
             };
 
             foreach (var binEnum in binEnums)
             {
                 Assert.IsTrue(binEnum.GetBinaryType().IsEnum);
 
-                Assert.AreEqual(val, binEnum.EnumValue);
+                Assert.AreEqual(intVal, binEnum.EnumValue);
+                Assert.AreEqual(enumVal.ToString(), binEnum.EnumName);
 
                 Assert.AreEqual(string.Format("{0} [typeId={1}, enumValue={2}, enumValueName={3}]",
-                    typeName, typeId, val, (TestEnumRegistered) val), binEnum.ToString());
+                    typeName, typeId, intVal, enumVal), binEnum.ToString());
 
-                Assert.AreEqual((TestEnumRegistered)val, binEnum.Deserialize<TestEnumRegistered>());
+                Assert.AreEqual(enumVal, binEnum.Deserialize<TestEnumRegistered>());
             }
 
             Assert.AreEqual(binEnums[0], binEnums[1]);
@@ -1687,6 +1701,60 @@ namespace Apache.Ignite.Core.Tests.Binary
         }
 
         /// <summary>
+        /// Tests enum registration.
+        /// </summary>
+        [Test]
+        public void TestRegisterEnum()
+        {
+            var binary = _grid.GetBinary();
+
+            // Register enum and verify resulting type.
+            const string typeName = "DotNetDynEnum";
+            var binType = binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz", 3}, {"Bar", 4}});
+
+            Assert.AreEqual(typeName, binType.TypeName);
+            Assert.IsTrue(binType.IsEnum);
+
+            var enumFields = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+            Assert.AreEqual(new[] {3, 4}, enumFields.Select(x => x.EnumValue));
+            Assert.AreEqual(new[] {"Baz", "Bar"}, enumFields.Select(x => x.EnumName));
+
+            // Build enum values.
+            var binEnum1 = binary.BuildEnum(typeName, 3);
+            var binEnum2 = binary.BuildEnum(typeName, "Baz");
+
+            Assert.AreEqual(binEnum1, binEnum2);
+            Assert.AreEqual("Baz", binEnum1.EnumName);
+            Assert.AreEqual(3, binEnum2.EnumValue);
+
+            // Register additional value explicitly.
+            binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Foo", 6}});
+            binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Foo", 6}, {"Baz", 3}});
+            binType = binary.GetBinaryType(typeName);
+
+            Assert.AreEqual(typeName, binType.TypeName);
+            Assert.IsTrue(binType.IsEnum);
+
+            enumFields = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+            Assert.AreEqual(new[] { 3, 4, 6 }, enumFields.Select(x => x.EnumValue));
+            Assert.AreEqual(new[] { "Baz", "Bar", "Foo" }, enumFields.Select(x => x.EnumName));
+
+            // Register existing value with different name.
+            var ex = Assert.Throws<BinaryObjectException>(
+                () => binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz1", 3}}));
+
+            Assert.AreEqual(string.Format("Conflicting enum values. Name 'Baz1' uses ordinal value (3) that " +
+                                          "is also used for name 'Baz' [typeName='{0}']", typeName), ex.Message);
+
+            // Register different value with existing name.
+            ex = Assert.Throws<BinaryObjectException>(
+                () => binary.RegisterEnum(typeName, new Dictionary<string, int> {{"Baz", 33}}));
+
+            Assert.AreEqual(string.Format("Conflicting enum values. Value (33) has name 'Baz' that is " +
+                                          "also used for value '3' [typeName='{0}']", typeName), ex.Message);
+        }
+
+        /// <summary>
         /// Tests the compact footer setting.
         /// </summary>
         [Test]
@@ -2102,13 +2170,13 @@ namespace Apache.Ignite.Core.Tests.Binary
         /** <inheritdoc /> */
         public int GetTypeId(string typeName)
         {
-            return typeName == TestTypeName ? TestTypeId : 0;
+            return typeName == TestTypeName ? TestTypeId : BinaryUtils.GetStringHashCode(typeName);
         }
 
         /** <inheritdoc /> */
         public int GetFieldId(int typeId, string fieldName)
         {
-            return 0;
+            return BinaryUtils.GetStringHashCode(fieldName);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 b9b7a04..1d8ceb9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs
@@ -122,6 +122,9 @@ namespace Apache.Ignite.Core.Tests.Compute
         /** Echo type: IgniteUuid. */
         private const int EchoTypeIgniteUuid = 22;
 
+        /** Echo type: binary enum (created with builder). */
+        private const int EchoTypeBinaryEnum = 23;
+
         /** */
         private const string DefaultCacheName = "default";
 
@@ -940,6 +943,28 @@ namespace Apache.Ignite.Core.Tests.Compute
         /// Tests the echo task returning enum.
         /// </summary>
         [Test]
+        public void TestEchoTaskBinaryEnum()
+        {
+            var res = _grid1.GetCompute().WithKeepBinary()
+                .ExecuteJavaTask<IBinaryObject>(EchoTask, EchoTypeBinaryEnum);
+
+            Assert.AreEqual("JavaFoo", res.EnumName);
+            Assert.AreEqual(1, res.EnumValue);
+
+            var binType = res.GetBinaryType();
+
+            Assert.IsTrue(binType.IsEnum);
+            Assert.AreEqual("JavaDynEnum", binType.TypeName);
+
+            var vals = binType.GetEnumValues().OrderBy(x => x.EnumValue).ToArray();
+            Assert.AreEqual(new[] {1, 2}, vals.Select(x => x.EnumValue));
+            Assert.AreEqual(new[] {"JavaFoo", "JavaBar"}, vals.Select(x => x.EnumName));
+        }
+
+        /// <summary>
+        /// Tests the echo task returning enum.
+        /// </summary>
+        [Test]
         public void TestEchoTaskEnumFromCache()
         {
             var cache = _grid1.GetCache<int, PlatformComputeEnum>(DefaultCacheName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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 c36b9fd..2d299f3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/BinaryTypeConfiguration.cs
@@ -18,6 +18,7 @@
 namespace Apache.Ignite.Core.Binary
 {
     using System;
+    using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
@@ -51,7 +52,7 @@ namespace Apache.Ignite.Core.Binary
             IgniteArgumentCheck.NotNull(type, "type");
 
             TypeName = type.AssemblyQualifiedName;
-            IsEnum = type.IsEnum;
+            IsEnum = BinaryUtils.IsIgniteEnum(type);
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c7b6f5/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
index f269681..671efa4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Binary/IBinary.cs
@@ -131,5 +131,29 @@ namespace Apache.Ignite.Core.Binary
         /// <param name="value">Enum int value.</param>
         /// <returns>Binary representation of the specified enum value.</returns>
         IBinaryObject BuildEnum(Type type, int value);
+
+        /// <summary>
+        /// Converts enum to a binary form.
+        /// </summary>
+        /// <param name="typeName">Enum type name.</param>
+        /// <param name="valueName">Enum value name.</param>
+        /// <returns>Binary representation of the specified enum value.</returns>
+        IBinaryObject BuildEnum(string typeName, string valueName);
+
+        /// <summary>
+        /// Converts enum to a binary form.
+        /// </summary>
+        /// <param name="type">Enum type.</param>
+        /// <param name="valueName">Enum value name.</param>
+        /// <returns>Binary representation of the specified enum value.</returns>
+        IBinaryObject BuildEnum(Type type, string valueName);
+
+        /// <summary>
+        /// Registers enum type.
+        /// </summary>
+        /// <param name="typeName">Name of the type.</param>
+        /// <param name="values">Mapping of enum value names to int values.</param>
+        /// <returns>Binary type for registered enum.</returns>
+        IBinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values);
     }
 }