http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs
new file mode 100644
index 0000000..9cb0907
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Continuous/ContinuousQueryJavaFilterTest.cs
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ReSharper disable UnusedAutoPropertyAccessor.Local
+#pragma warning disable 618  // SpringConfigUrl
+namespace Apache.Ignite.Core.Tests.Cache.Query.Continuous
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Threading;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Cache.Event;
+    using Apache.Ignite.Core.Cache.Query.Continuous;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Interop;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests query in a cluster with Java-only and .NET nodes.
+    /// </summary>
+    public class ContinuousQueryJavaFilterTest
+    {
+        /** */
+        private const string SpringConfig = 
@"Config\Compute\compute-grid1.xml";
+
+        /** */
+        private const string SpringConfig2 = 
@"Config\Compute\compute-grid2.xml";
+
+        /** */
+        private const string StartTask = 
"org.apache.ignite.platform.PlatformStartIgniteTask";
+
+        /** */
+        private const string StopTask = 
"org.apache.ignite.platform.PlatformStopIgniteTask";
+
+        /** */
+        private IIgnite _ignite;
+        
+        /** */
+        private string _javaNodeName;
+
+        /** */
+        private static volatile ICacheEntryEvent<int, string> _lastEvent;
+
+        /// <summary>
+        /// Fixture set up.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void FixtureSetUp()
+        {
+            // Main .NET nodes
+            IList<String> jvmOpts = TestUtils.TestJavaOptions();
+
+            _ignite = Ignition.Start(new IgniteConfiguration
+            {
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                JvmOptions = jvmOpts,
+                SpringConfigUrl = SpringConfig,
+                BinaryConfiguration = new BinaryConfiguration
+                {
+                    TypeConfigurations = new List<BinaryTypeConfiguration>
+                    {
+                        new BinaryTypeConfiguration(typeof(TestBinary)) 
+                    }
+                }
+            });
+
+            // Second .NET node
+            Ignition.Start(new IgniteConfigurationEx
+            {
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                JvmOptions = jvmOpts,
+                SpringConfigUrl = SpringConfig2,
+                GridName = "dotNet2"
+            });
+
+            // Java-only node
+            _javaNodeName = 
_ignite.GetCompute().ExecuteJavaTask<string>(StartTask, SpringConfig2);
+
+            Assert.IsTrue(_ignite.WaitTopology(3, 5000));
+        }
+
+        /// <summary>
+        /// Fixture tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            _ignite.GetCompute().ExecuteJavaTask<object>(StopTask, 
_javaNodeName);
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests the filter.
+        /// </summary>
+        [Test]
+        public void TestFilter()
+        {
+            var javaObj = new 
JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilter")
+            {
+                Properties =
+                {
+                    {"startsWith", "valid"},
+                    {"charField", 'a'},
+                    {"byteField", (byte) 1},
+                    {"sbyteField", (sbyte) 2},
+                    {"shortField", (short) 3},
+                    {"ushortField", (ushort) 4},
+                    {"intField", 5},
+                    {"uintField", (uint) 6},
+                    {"longField", (long) 7},
+                    {"ulongField", (ulong) 8},
+                    {"floatField", (float) 9.99},
+                    {"doubleField", 10.123},
+                    {"decimalField", (decimal) 11.245},
+                    {"boolField", true},
+                    {"guidField", 
Guid.Parse("1c579241-509d-47c6-a1a0-87462ae31e59")},
+                    {
+                        "objField", new TestBinary
+                        {
+                            Int = 1,
+                            String = "2"
+                        }
+                    },
+                    {"charArr", new[] {'a'}},
+                    {"byteArr", new[] {(byte) 1}},
+                    {"sbyteArr", new[] {(sbyte) 2}},
+                    {"shortArr", new[] {(short) 3}},
+                    {"ushortArr", new[] {(ushort) 4}},
+                    {"intArr", new[] {5}},
+                    {"uintArr", new[] {(uint) 6}},
+                    {"longArr", new[] {(long) 7}},
+                    {"ulongArr", new[] {(ulong) 8}},
+                    {"floatArr", new[] {(float) 9.99}},
+                    {"doubleArr", new[] {10.123}},
+                    {"boolArr", new[] {true}},
+                    {
+                        "objArr", new object[]
+                        {
+                            new TestBinary
+                            {
+                                Int = 1,
+                                String = "2"
+                            }
+                        }
+                    },
+                    {"arrayList", new ArrayList {"x"}},
+                    {"hashTable", new Hashtable {{1, "2"}}}
+                }
+            };
+
+            var filter = javaObj.ToCacheEntryEventFilter<int, string>();
+
+            TestFilter(filter);
+        }
+
+        /// <summary>
+        /// Tests the factory class.
+        /// </summary>
+        [Test]
+        public void TestFactory()
+        {
+            var javaObj = new 
JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilterFactory",
+                new Dictionary<string, object> {{"startsWith", "valid"}});
+
+            var filter = javaObj.ToCacheEntryEventFilter<int, string>();
+
+            TestFilter(filter);
+        }
+
+        /// <summary>
+        /// Tests the invalid class name
+        /// </summary>
+        [Test]
+        public void TestInvalidClassName()
+        {
+            var filter = new JavaObject("blabla").ToCacheEntryEventFilter<int, 
string>();
+
+            var ex = Assert.Throws<IgniteException>(() => TestFilter(filter));
+
+            Assert.IsTrue(ex.Message.StartsWith("Java object/factory class is 
not found"));
+        }
+
+        /// <summary>
+        /// Tests the invalid class name
+        /// </summary>
+        [Test]
+        public void TestInvalidProperty()
+        {
+            var javaObject = new 
JavaObject("org.apache.ignite.platform.PlatformCacheEntryEventFilter")
+            {
+                Properties = {{"invalidProp", "123"}}
+            };
+
+            var filter = javaObject.ToCacheEntryEventFilter<int, string>();
+
+            var ex = Assert.Throws<IgniteException>(() => TestFilter(filter));
+
+            Assert.IsTrue(ex.Message.StartsWith("Java object/factory class 
field is not found"));
+        }
+
+        /// <summary>
+        /// Tests the specified filter.
+        /// </summary>
+        private void TestFilter(ICacheEntryEventFilter<int, string> pred)
+        {
+            TestFilter(pred, false);
+            TestFilter(pred, true);
+        }
+
+        /// <summary>
+        /// Tests the specified filter.
+        /// </summary>
+        private void TestFilter(ICacheEntryEventFilter<int, string> pred, bool 
local)
+        {
+            var cache = _ignite.GetOrCreateCache<int, string>("qry");
+            var qry = new ContinuousQuery<int, string>(new QueryListener(), 
pred, local);
+            var aff = _ignite.GetAffinity("qry");
+            var localNode = _ignite.GetCluster().GetLocalNode();
+
+            // Get one key per node
+            var keyMap = aff.MapKeysToNodes(Enumerable.Range(1, 100));
+            Assert.AreEqual(3, keyMap.Count);
+            var keys = local
+                ? keyMap[localNode].Take(1)
+                : keyMap.Select(x => x.Value.First());
+
+            using (cache.QueryContinuous(qry))
+            {
+                // Run on many keys to test all nodes
+                foreach (var key in keys)
+                {
+                    _lastEvent = null;
+                    cache[key] = "validValue";
+
+                    TestUtils.WaitForCondition(() => _lastEvent != null, 2000);
+                    Assert.IsNotNull(_lastEvent);
+                    Assert.AreEqual(cache[key], _lastEvent.Value);
+
+                    _lastEvent = null;
+                    cache[key] = "invalidValue";
+
+                    Thread.Sleep(2000);
+                    Assert.IsNull(_lastEvent);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Test listener.
+        /// </summary>
+        private class QueryListener : ICacheEntryEventListener<int, string>
+        {
+            /** <inheritdoc /> */
+            public void OnEvent(IEnumerable<ICacheEntryEvent<int, string>> 
evts)
+            {
+                _lastEvent = evts.FirstOrDefault();
+            }
+        }
+
+        /// <summary>
+        /// Test binary object.
+        /// </summary>
+        private class TestBinary
+        {
+            public int Int { get; set; }
+            public string String { get; set; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
index 3061773..78a30a8 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid1.xml
@@ -69,7 +69,6 @@
                         </bean>
                     </list>
                 </property>
-
             </bean>
         </property>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml
 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml
index ef29a89..f32e0bb 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/Compute/compute-grid2.xml
@@ -62,7 +62,16 @@
                         </bean>
                     </list>
                 </property>
-
+                <property name="idMapper">
+                    <bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
+                        <constructor-arg value="true"/>
+                    </bean>
+                </property>
+                <property name="nameMapper">
+                    <bean 
class="org.apache.ignite.binary.BinaryBasicNameMapper">
+                        <constructor-arg value="true"/>
+                    </bean>
+                </property>
             </bean>
         </property>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj 
b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 12404be..05a7fa7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -80,6 +80,7 @@
     <Compile Include="Cache\IMutableCacheEntry.cs" />
     <Compile Include="Cache\Package-Info.cs" />
     <Compile Include="Cache\Query\Continuous\ContinuousQuery.cs" />
+    <Compile Include="Cache\Query\Continuous\ContinuousQueryExtensions.cs" />
     <Compile Include="Cache\Query\Continuous\IContinuousQueryHandle.cs" />
     <Compile Include="Cache\Query\Continuous\Package-Info.cs" />
     <Compile Include="Cache\Query\IQueryCursor.cs" />
@@ -107,6 +108,8 @@
     <Compile Include="Common\IgniteFutureCancelledException.cs" />
     <Compile Include="Common\IgniteGuid.cs" />
     <Compile Include="Common\Package-Info.cs" />
+    <Compile Include="Impl\Cache\Event\JavaCacheEntryEventFilter.cs" />
+    <Compile Include="Impl\Common\PlatformJavaObjectFactoryProxy.cs" />
     <Compile Include="Compute\ComputeExecutionRejectedException.cs" />
     <Compile Include="Compute\ComputeJobAdapter.cs" />
     <Compile Include="Compute\ComputeJobFailoverException.cs" />
@@ -324,6 +327,7 @@
     <Compile Include="Impl\Unmanaged\UnmanagedNonReleaseableTarget.cs" />
     <Compile Include="Impl\Unmanaged\UnmanagedTarget.cs" />
     <Compile Include="Impl\Unmanaged\UnmanagedUtils.cs" />
+    <Compile Include="Interop\JavaObject.cs" />
     <Compile Include="Lifecycle\Package-Info.cs" />
     <Compile Include="Messaging\Package-Info.cs" />
     <Compile Include="Package-Info.cs" />
@@ -399,6 +403,9 @@
   <ItemGroup>
     <None Include="Apache.Ignite.Core.snk" />
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Impl\Common\JavaObjects\" />
+  </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.
@@ -407,4 +414,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file
+</Project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs
new file mode 100644
index 0000000..50cbe9f
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQueryExtensions.cs
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Query.Continuous
+{
+    using Apache.Ignite.Core.Cache.Event;
+    using Apache.Ignite.Core.Impl.Cache.Event;
+    using Apache.Ignite.Core.Interop;
+
+    /// <summary>
+    /// Extensions for continuous queries.
+    /// </summary>
+    public static class ContinuousQueryExtensions
+    {
+        /// <summary>
+        /// Creates the cache event filter that delegates to the corresponding 
Java object.
+        /// </summary>
+        /// <typeparam name="TK">Key type.</typeparam>
+        /// <typeparam name="TV">Value type.</typeparam>
+        public static ICacheEntryEventFilter<TK, TV> 
ToCacheEntryEventFilter<TK, TV>(this JavaObject javaObject)
+        {
+            return new JavaCacheEntryEventFilter<TK, TV>(javaObject.ClassName, 
javaObject.Properties);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/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 1c85e31..80e5b26 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryUtils.cs
@@ -187,6 +187,9 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** Type: stream receiver holder. */
         public const byte TypeStreamReceiverHolder = 94;
 
+        /** Type: platform object proxy. */
+        public const byte TypePlatformJavaObjectFactoryProxy = 99;
+
         /** Collection: custom. */
         public const byte CollectionCustom = 0;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/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 457830f..81fc195 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Impl.Binary
     using Apache.Ignite.Core.Impl.Binary.Metadata;
     using Apache.Ignite.Core.Impl.Cache;
     using Apache.Ignite.Core.Impl.Cache.Query.Continuous;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Compute;
     using Apache.Ignite.Core.Impl.Compute.Closure;
     using Apache.Ignite.Core.Impl.Datastream;
@@ -534,6 +535,7 @@ namespace Apache.Ignite.Core.Impl.Binary
             AddSystemType(BinaryUtils.TypeCacheEntryPredicateHolder, w => new 
CacheEntryFilterHolder(w));
             AddSystemType(BinaryUtils.TypeMessageListenerHolder, w => new 
MessageListenerHolder(w));
             AddSystemType(BinaryUtils.TypeStreamReceiverHolder, w => new 
StreamReceiverHolder(w));
+            AddSystemType(BinaryUtils.TypePlatformJavaObjectFactoryProxy, w => 
new PlatformJavaObjectFactoryProxy());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs
new file mode 100644
index 0000000..b5c2ece
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Event/JavaCacheEntryEventFilter.cs
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Cache.Event
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cache.Event;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Cache entry event filter that delegates to Java.
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    internal class JavaCacheEntryEventFilter<TK, TV> : 
PlatformJavaObjectFactoryProxy, ICacheEntryEventFilter<TK, TV>
+    {
+        /** <inheritdoc /> */
+        public bool Evaluate(ICacheEntryEvent<TK, TV> evt)
+        {
+            throw new InvalidOperationException(GetType() + " cannot be 
invoked directly.");
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="JavaCacheEntryEventFilter{TK, TV}"/> class.
+        /// </summary>
+        /// <param name="factoryClassName">Name of the factory class.</param>
+        /// <param name="properties">The properties.</param>
+        public JavaCacheEntryEventFilter(string factoryClassName, 
IDictionary<string, object> properties) 
+            : base(FactoryType.User, factoryClassName, null, properties)
+        {
+            // No-op.
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs
index fef904b..101ed43 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/Continuous/ContinuousQueryHandleImpl.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query.Continuous
     using Apache.Ignite.Core.Cache.Query.Continuous;
     using Apache.Ignite.Core.Impl.Binary;
     using Apache.Ignite.Core.Impl.Binary.IO;
+    using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Resource;
     using Apache.Ignite.Core.Impl.Unmanaged;
     using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
@@ -111,10 +112,20 @@ namespace Apache.Ignite.Core.Impl.Cache.Query.Continuous
             writer.WriteBoolean(qry.Local);
             writer.WriteBoolean(_filter != null);
 
-            var filterHolder = _filter == null || qry.Local ? null :
-                new ContinuousQueryFilterHolder(_filter, _keepBinary);
+            var javaFilter = _filter as PlatformJavaObjectFactoryProxy;
 
-            writer.WriteObject(filterHolder);
+            if (javaFilter != null)
+            {
+                writer.WriteObject(javaFilter.GetRawProxy());
+            }
+            else
+            {
+                var filterHolder = _filter == null || qry.Local
+                    ? null
+                    : new ContinuousQueryFilterHolder(_filter, _keepBinary);
+
+                writer.WriteObject(filterHolder);
+            }
 
             writer.WriteInt(qry.BufferSize);
             writer.WriteLong((long)qry.TimeInterval.TotalMilliseconds);

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs
----------------------------------------------------------------------
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs
new file mode 100644
index 0000000..89b2891
--- /dev/null
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PlatformJavaObjectFactoryProxy.cs
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Impl.Common
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary;
+
+    /// <summary>
+    /// Maps to PlatformJavaObjectFactoryProxy in Java.
+    /// </summary>
+    internal class PlatformJavaObjectFactoryProxy : IBinaryWriteAware
+    {
+        /// <summary>
+        /// Represents the factory type.
+        /// </summary>
+        internal enum FactoryType
+        {
+            User = 0,
+            Default = 1
+        }
+
+        /** Type code. */
+        private readonly FactoryType _factoryType;
+
+        /** Java class name */
+        private readonly string _factoryClassName;
+
+        /** Optional payload. */
+        private readonly object _payload;
+
+        /** Properties to set */
+        private readonly IDictionary<string, object> _properties;
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="PlatformJavaObjectFactoryProxy" /> class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <param name="factoryClassName">Name of the factory class.</param>
+        /// <param name="payload">The payload.</param>
+        /// <param name="properties">The properties.</param>
+        protected PlatformJavaObjectFactoryProxy(FactoryType type, string 
factoryClassName, object payload, 
+            IDictionary<string, object> properties)
+        {
+            _factoryType = type;
+            _factoryClassName = factoryClassName;
+            _payload = payload;
+            _properties = properties;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see 
cref="PlatformJavaObjectFactoryProxy"/> class.
+        /// </summary>
+        public PlatformJavaObjectFactoryProxy()
+        {
+            throw new InvalidOperationException(GetType() + " should never be 
deserialized on .NET side.");
+        }
+
+        /** <inheritdoc /> */
+        public void WriteBinary(IBinaryWriter writer)
+        {
+            var w = writer.GetRawWriter();
+
+            w.WriteInt((int) _factoryType);
+            w.WriteString(_factoryClassName);
+            w.WriteObject(_payload);
+
+            if (_properties != null)
+            {
+                w.WriteInt(_properties.Count);
+
+                foreach (var pair in _properties)
+                {
+                    w.WriteString(pair.Key);
+                    w.WriteObject(pair.Value);
+                }
+            }
+            else
+                w.WriteInt(0);
+        }
+
+        /// <summary>
+        /// Gets the raw proxy (not the derived type) for serialization.
+        /// </summary>
+        public PlatformJavaObjectFactoryProxy GetRawProxy()
+        {
+            return new PlatformJavaObjectFactoryProxy(_factoryType, 
_factoryClassName, _payload, _properties);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/218c4b6a/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs 
b/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs
new file mode 100644
index 0000000..98ef619
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Interop/JavaObject.cs
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Interop
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Impl.Common;
+
+    /// <summary>
+    /// Represents a Java object wrapper.
+    /// <para />
+    /// <see cref="JavaObject"/> can be converted to Ignite filters and 
predicates 
+    /// which can be used on non-.NET Ignite nodes.
+    /// <para />
+    /// Workflow is as follows:
+    /// Instantiate specified Java class;
+    /// Set property values;
+    /// If the resulting object implements PlatformJavaObjectFactory, call 
create() method and use the result,
+    /// otherwise use the original object.
+    /// </summary>
+    public class JavaObject
+    {
+        /** Java class name. */
+        private readonly string _className;
+
+        /** Properties. */
+        private readonly IDictionary<string, object> _properties = new 
Dictionary<string, object>();
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="JavaObject"/> class.
+        /// </summary>
+        /// <param name="className">Name of the Java class.</param>
+        public JavaObject(string className)
+        {
+            IgniteArgumentCheck.NotNullOrEmpty(className, "className");
+
+            _className = className;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="JavaObject"/> class.
+        /// </summary>
+        /// <param name="className">Name of the Java class.</param>
+        /// <param name="properties">The properties to set on the Java 
object.</param>
+        public JavaObject(string className, IDictionary<string, object> 
properties) : this(className)
+        {
+            _properties = properties ?? _properties;
+        }
+
+        /// <summary>
+        /// Gets the Java class name.
+        /// </summary>
+        public string ClassName
+        {
+            get { return _className; }
+        }
+
+        /// <summary>
+        /// Gets the properties to be set on the Java object.
+        /// </summary>
+        public IDictionary<string, object> Properties
+        {
+            get { return _properties; }
+        }
+    }
+}

Reply via email to