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

[30/37] ignite git commit: IGNITE-1513: WIP on .Net.

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
new file mode 100644
index 0000000..9af4611
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache-store.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="includeEventTypes">
+            <util:constant static-field="org.apache.ignite.events.EventType.EVTS_CACHE"/>
+        </property>
+
+        <property name="cacheConfiguration">
+            <list>
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="portable_store"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="readThrough" value="true"/>
+
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory">
+                            <property name="assemblyName" value="Apache.Ignite.Core.Tests"/>
+                            <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/>
+                        </bean>
+                    </property>
+                </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="object_store"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="readThrough" value="true"/>
+                    <property name="keepPortableInStore" value="false"/>
+
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory">
+                            <property name="assemblyName" value="Apache.Ignite.Core.Tests"/>
+                            <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/>
+                        </bean>
+                    </property>
+                </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="template_store*"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="readThrough" value="true"/>
+                    <property name="keepPortableInStore" value="false"/>
+
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory">
+                            <property name="assemblyName" value="Apache.Ignite.Core.Tests"/>
+                            <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/>
+                        </bean>
+                    </property>
+                </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="custom_store"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="readThrough" value="true"/>
+                    
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.platform.dotnet.PlatformDotNetCacheStoreFactory">
+                            <property name="assemblyName" value="Apache.Ignite.Core.Tests"/>
+                            <property name="className" value="Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore"/>
+                            <property name="properties">
+                                <map>
+                                    <entry key="IntProperty">
+                                        <value type="java.lang.Integer">42</value>
+                                    </entry>
+                                    <entry key="StringProperty" value="String value"/>
+                                </map>
+                            </property>
+                        </bean>
+                    </property>
+                </bean>
+            </list>
+        </property>
+
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47501</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml
new file mode 100644
index 0000000..c48e867
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/native-client-test-cache.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="includeEventTypes">
+            <util:constant static-field="org.apache.ignite.events.EventType.EVTS_CACHE"/>
+        </property>
+
+        <property name="cacheConfiguration">
+            <list>
+                <bean parent="cache-template">
+                    <property name="name" value="local"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="local_atomic"/>
+                    <property name="cacheMode" value="LOCAL"/>
+                    <property name="atomicityMode" value="ATOMIC"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="partitioned"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="partitioned_atomic"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="ATOMIC"/>
+                    <property name="atomicWriteOrderMode" value="PRIMARY"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="partitioned_near"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="nearConfiguration">
+                        <bean class="org.apache.ignite.configuration.NearCacheConfiguration" />
+                    </property>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="partitioned_atomic_near"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="ATOMIC"/>
+                    <property name="atomicWriteOrderMode" value="PRIMARY"/>
+                    <property name="nearConfiguration">
+                        <bean class="org.apache.ignite.configuration.NearCacheConfiguration" />
+                    </property>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="replicated"/>
+                    <property name="cacheMode" value="REPLICATED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+
+                <bean parent="cache-template">
+                    <property name="name" value="replicated_atomic"/>
+                    <property name="cacheMode" value="REPLICATED"/>
+                    <property name="atomicityMode" value="ATOMIC"/>
+                    <property name="atomicWriteOrderMode" value="PRIMARY"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+                
+                <bean parent="cache-template">
+                    <property name="name" value="template*"/>
+                    <property name="startSize" value="10"/>
+                </bean>
+            </list>
+        </property>
+
+        <property name="swapSpaceSpi">
+            <bean class="org.apache.ignite.spi.swapspace.inmemory.GridTestSwapSpaceSpi"/>
+        </property>
+
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47501</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+
+        <property name="transactionConfiguration">
+            <bean class="org.apache.ignite.configuration.TransactionConfiguration">
+                <property name="txSerializableEnabled" value="true"/>
+            </bean>
+        </property>
+    </bean>
+
+    <bean id="cache-template" abstract="true" class="org.apache.ignite.configuration.CacheConfiguration">
+        <property name="rebalanceMode" value="SYNC"/>
+        <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+        <property name="swapEnabled" value="true"/>
+        <property name="backups" value="1"/>
+        <property name="eagerTtl" value="true"/>
+
+        <!--
+        <property name="typeMetadata">
+            <list>
+                <bean class="org.apache.ignite.cache.CacheTypeMetadata">
+                    <property name="valueType" value="GridPortablePerson"/>
+                    <property name="ascendingFields">
+                        <map>
+                            <entry key="age" value="java.lang.Integer"/>
+                        </map>
+                    </property>
+                    <property name="queryFields">
+                        <map>
+                            <entry key="name" value="java.lang.String"/>
+                        </map>
+                    </property>
+                    <property name="textFields">
+                        <list>
+                            <value>address</value>
+                        </list>
+                    </property>
+                </bean>
+                <bean class="org.apache.ignite.cache.CacheTypeMetadata">
+                    <property name="valueType" value="GridImplicitPortablePerson"/>
+                    <property name="ascendingFields">
+                        <map>
+                            <entry key="age" value="java.lang.Integer"/>
+                        </map>
+                    </property>
+                    <property name="queryFields">
+                        <map>
+                            <entry key="name" value="java.lang.String"/>
+                        </map>
+                    </property>
+                </bean>
+                <bean class="org.apache.ignite.cache.CacheTypeMetadata">
+                    <property name="valueType" value="GridNoDefPortablePerson"/>
+                    <property name="ascendingFields">
+                        <map>
+                            <entry key="age" value="java.lang.Integer"/>
+                        </map>
+                    </property>
+                    <property name="queryFields">
+                        <map>
+                            <entry key="name" value="java.lang.String"/>
+                        </map>
+                    </property>
+                </bean>
+            </list>
+        </property>
+        -->
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml
new file mode 100644
index 0000000..f013749
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/portable.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="gridName" value="grid"/>
+
+        <property name="metricsUpdateFrequency" value="1000"/>
+        <property name="metricsLogFrequency" value="0"/>
+
+        <property name="cacheConfiguration">
+            <list>
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache"/>
+                </bean>
+            </list>
+        </property>
+      
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47502</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml
new file mode 100644
index 0000000..8559173
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid1.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="gridName" value="grid1"/>
+
+        <property name="cacheConfiguration">
+            <list>
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache1"/>
+                    <property name="rebalanceMode" value="SYNC"/>
+                </bean>
+            </list>
+        </property>
+
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47502</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml
new file mode 100644
index 0000000..cb628fe
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid2.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="gridName" value="grid2"/>
+
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47502</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml
new file mode 100644
index 0000000..753fad1
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Config/start-test-grid3.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500..47502</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
new file mode 100644
index 0000000..245ed5f
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs
@@ -0,0 +1,592 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Dataload
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Linq;
+    using System.Threading;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Datastream;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Tests.Cache;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Data streamer tests.
+    /// </summary>
+    public class DataStreamerTest
+    {
+        /** Node name. */
+        protected const string GridName = "grid";
+
+        /** Cache name. */
+        protected const string CacheName = "partitioned";
+
+        /** Node. */
+        private IIgnite _grid;
+
+        /** Cache. */
+        private ICache<int, int?> _cache;
+
+        /// <summary>
+        /// Initialization routine.
+        /// </summary>
+        [TestFixtureSetUp]
+        public virtual void InitClient()
+        {
+            _grid = Ignition.Start(GetIgniteConfiguration(GridName));
+
+            Ignition.Start(GetIgniteConfiguration(GridName + "_1"));
+
+            _cache = _grid.GetCache<int, int?>(CacheName);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [TestFixtureTearDown]
+        public virtual void StopGrids()
+        {
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        [SetUp]
+        public virtual void BeforeTest()
+        {
+            Console.WriteLine("Test started: " + TestContext.CurrentContext.Test.Name);
+
+            for (int i = 0; i < 100; i++)
+                _cache.Remove(i);
+        }
+
+        [TearDown]
+        public void AfterTest()
+        {
+            TestUtils.AssertHandleRegistryIsEmpty(_grid, 1000);
+        }
+
+        /// <summary>
+        /// Test data streamer property configuration. Ensures that at least no exceptions are thrown.
+        /// </summary>
+        [Test]
+        public void TestPropertyPropagation()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                ldr.AllowOverwrite = true;
+                Assert.IsTrue(ldr.AllowOverwrite);
+                ldr.AllowOverwrite = false;
+                Assert.IsFalse(ldr.AllowOverwrite);
+
+                ldr.SkipStore = true;
+                Assert.IsTrue(ldr.SkipStore);
+                ldr.SkipStore = false;
+                Assert.IsFalse(ldr.SkipStore);
+
+                ldr.PerNodeBufferSize = 1;
+                Assert.AreEqual(1, ldr.PerNodeBufferSize);
+                ldr.PerNodeBufferSize = 2;
+                Assert.AreEqual(2, ldr.PerNodeBufferSize);
+
+                ldr.PerNodeParallelOperations = 1;
+                Assert.AreEqual(1, ldr.PerNodeParallelOperations);
+                ldr.PerNodeParallelOperations = 2;
+                Assert.AreEqual(2, ldr.PerNodeParallelOperations);
+            }
+        }
+
+        /// <summary>
+        /// Test data add/remove.
+        /// </summary>
+        [Test]        
+        public void TestAddRemove()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                ldr.AllowOverwrite = true;
+
+                // Additions.
+                ldr.AddData(1, 1);
+                ldr.Flush();                
+                Assert.AreEqual(1, _cache.Get(1));
+
+                ldr.AddData(new KeyValuePair<int, int>(2, 2));
+                ldr.Flush();
+                Assert.AreEqual(2, _cache.Get(2));
+
+                ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(3, 3), new KeyValuePair<int, int>(4, 4) });
+                ldr.Flush();
+                Assert.AreEqual(3, _cache.Get(3));
+                Assert.AreEqual(4, _cache.Get(4));
+
+                // Removal.
+                ldr.RemoveData(1);
+                ldr.Flush();
+                Assert.IsNull(_cache.Get(1));
+
+                // Mixed.
+                ldr.AddData(5, 5);                
+                ldr.RemoveData(2);
+                ldr.AddData(new KeyValuePair<int, int>(7, 7));
+                ldr.AddData(6, 6);
+                ldr.RemoveData(4);
+                ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(9, 9), new KeyValuePair<int, int>(10, 10) });
+                ldr.AddData(new KeyValuePair<int, int>(8, 8));
+                ldr.RemoveData(3);
+                ldr.AddData(new List<KeyValuePair<int, int>> { new KeyValuePair<int, int>(11, 11), new KeyValuePair<int, int>(12, 12) });
+
+                ldr.Flush();
+
+                for (int i = 2; i < 5; i++)
+                    Assert.IsNull(_cache.Get(i));
+
+                for (int i = 5; i < 13; i++)
+                    Assert.AreEqual(i, _cache.Get(i));
+            }
+        }
+
+        /// <summary>
+        /// Test "tryFlush".
+        /// </summary>
+        [Test]
+        public void TestTryFlush()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                var fut = ldr.AddData(1, 1);
+
+                ldr.TryFlush();
+
+                fut.Get();
+
+                Assert.AreEqual(1, _cache.Get(1));
+            }
+        }
+
+        /// <summary>
+        /// Test buffer size adjustments.
+        /// </summary>
+        [Test]
+        public void TestBufferSize()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                var fut = ldr.AddData(1, 1);
+
+                Thread.Sleep(100);
+
+                Assert.IsFalse(fut.IsDone);
+
+                ldr.PerNodeBufferSize = 2;
+
+                ldr.AddData(2, 2);
+                ldr.AddData(3, 3);
+                ldr.AddData(4, 4).Get();
+                fut.Get();
+
+                Assert.AreEqual(1, _cache.Get(1));
+                Assert.AreEqual(2, _cache.Get(2));
+                Assert.AreEqual(3, _cache.Get(3));
+                Assert.AreEqual(4, _cache.Get(4));
+
+                ldr.AddData(new List<KeyValuePair<int, int>>
+                {
+                    new KeyValuePair<int, int>(5, 5), 
+                    new KeyValuePair<int, int>(6, 6),
+                    new KeyValuePair<int, int>(7, 7), 
+                    new KeyValuePair<int, int>(8, 8)
+                }).Get();
+
+                Assert.AreEqual(5, _cache.Get(5));
+                Assert.AreEqual(6, _cache.Get(6));
+                Assert.AreEqual(7, _cache.Get(7));
+                Assert.AreEqual(8, _cache.Get(8));
+            }
+        }
+
+        /// <summary>
+        /// Test close.
+        /// </summary>
+        [Test]
+        public void TestClose()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                var fut = ldr.AddData(1, 1);
+
+                ldr.Close(false);
+
+                fut.Get();
+
+                Assert.AreEqual(1, _cache.Get(1));
+            }
+        }
+
+        /// <summary>
+        /// Test close with cancellation.
+        /// </summary>
+        [Test]
+        public void TestCancel()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                var fut = ldr.AddData(1, 1);
+
+                ldr.Close(true);
+
+                fut.Get();
+
+                Assert.IsNull(_cache.Get(1));
+            }
+        }
+
+        /// <summary>
+        /// Tests that streamer gets collected when there are no references to it.
+        /// </summary>
+        [Test]
+        public void TestFinalizer()
+        {
+            var streamer = _grid.GetDataStreamer<int, int>(CacheName);
+            var streamerRef = new WeakReference(streamer);
+
+            Assert.IsNotNull(streamerRef.Target);
+
+            // ReSharper disable once RedundantAssignment
+            streamer = null;
+
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+
+            Assert.IsNull(streamerRef.Target);
+        }
+
+        /// <summary>
+        /// Test auto-flush feature.
+        /// </summary>
+        [Test]
+        public void TestAutoFlush()
+        {
+            using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                // Test auto flush turning on.
+                var fut = ldr.AddData(1, 1);
+                Thread.Sleep(100);
+                Assert.IsFalse(fut.IsDone);
+                ldr.AutoFlushFrequency = 1000;                
+                fut.Get();
+
+                // Test forced flush after frequency change.
+                fut = ldr.AddData(2, 2);
+                ldr.AutoFlushFrequency = long.MaxValue;                
+                fut.Get();
+
+                // Test another forced flush after frequency change.
+                fut = ldr.AddData(3, 3);
+                ldr.AutoFlushFrequency = 1000;
+                fut.Get();
+
+                // Test flush before stop.
+                fut = ldr.AddData(4, 4);
+                ldr.AutoFlushFrequency = 0;
+                fut.Get();
+
+                // Test flush after second turn on.
+                fut = ldr.AddData(5, 5);
+                ldr.AutoFlushFrequency = 1000;
+                fut.Get();
+
+                Assert.AreEqual(1, _cache.Get(1));
+                Assert.AreEqual(2, _cache.Get(2));
+                Assert.AreEqual(3, _cache.Get(3));
+                Assert.AreEqual(4, _cache.Get(4));
+                Assert.AreEqual(5, _cache.Get(5));
+            }
+        }
+
+        /// <summary>
+        /// Test multithreaded behavior. 
+        /// </summary>
+        [Test]
+        [Category(TestUtils.CategoryIntensive)]
+        public void TestMultithreaded()
+        {
+            int entriesPerThread = 100000;
+            int threadCnt = 8;
+
+            for (int i = 0; i < 5; i++)
+            {
+                _cache.Clear();
+
+                Assert.AreEqual(0, _cache.GetSize());
+
+                Stopwatch watch = new Stopwatch();
+
+                watch.Start();
+
+                using (IDataStreamer<int, int> ldr = _grid.GetDataStreamer<int, int>(CacheName))
+                {
+                    ldr.PerNodeBufferSize = 1024;
+
+                    int ctr = 0;
+
+                    TestUtils.RunMultiThreaded(() =>
+                    {
+                        int threadIdx = Interlocked.Increment(ref ctr);
+
+                        int startIdx = (threadIdx - 1) * entriesPerThread;
+                        int endIdx = startIdx + entriesPerThread;
+
+                        for (int j = startIdx; j < endIdx; j++)
+                        {
+                            // ReSharper disable once AccessToDisposedClosure
+                            ldr.AddData(j, j);
+
+                            if (j % 100000 == 0)
+                                Console.WriteLine("Put [thread=" + threadIdx + ", cnt=" + j  + ']');
+                        }
+                    }, threadCnt);
+                }
+
+                Console.WriteLine("Iteration " + i + ": " + watch.ElapsedMilliseconds);
+
+                watch.Reset();
+
+                for (int j = 0; j < threadCnt * entriesPerThread; j++)
+                    Assert.AreEqual(j, j);
+            }
+        }
+
+        /// <summary>
+        /// Tests custom receiver.
+        /// </summary>
+        [Test]
+        public void TestStreamReceiver()
+        {
+            TestStreamReceiver(new StreamReceiverPortable());
+            TestStreamReceiver(new StreamReceiverSerializable());
+        }
+
+        /// <summary>
+        /// Tests StreamVisitor.
+        /// </summary>
+        [Test]
+        public void TestStreamVisitor()
+        {
+            TestStreamReceiver(new StreamVisitor<int, int>((c, e) => c.Put(e.Key, e.Value + 1)));
+        }
+
+        /// <summary>
+        /// Tests StreamTransformer.
+        /// </summary>
+        [Test]
+        public void TestStreamTransformer()
+        {
+            TestStreamReceiver(new StreamTransformer<int, int, int, int>(new EntryProcessorSerializable()));
+            TestStreamReceiver(new StreamTransformer<int, int, int, int>(new EntryProcessorPortable()));
+        }
+
+        /// <summary>
+        /// Tests specified receiver.
+        /// </summary>
+        private void TestStreamReceiver(IStreamReceiver<int, int> receiver)
+        {
+            using (var ldr = _grid.GetDataStreamer<int, int>(CacheName))
+            {
+                ldr.AllowOverwrite = true;
+
+                ldr.Receiver = new StreamReceiverPortable();
+
+                ldr.Receiver = receiver;  // check double assignment
+
+                Assert.AreEqual(ldr.Receiver, receiver);
+
+                for (var i = 0; i < 100; i++)
+                    ldr.AddData(i, i);
+
+                ldr.Flush();
+
+                for (var i = 0; i < 100; i++)
+                    Assert.AreEqual(i + 1, _cache.Get(i));
+            }
+        }
+
+        /// <summary>
+        /// Tests the stream receiver in keepPortable mode.
+        /// </summary>
+        [Test]
+        public void TestStreamReceiverKeepPortable()
+        {
+            // ReSharper disable once LocalVariableHidesMember
+            var cache = _grid.GetCache<int, PortableEntry>(CacheName);
+
+            using (var ldr0 = _grid.GetDataStreamer<int, int>(CacheName))
+            using (var ldr = ldr0.WithKeepPortable<int, IPortableObject>())
+            {
+                ldr.Receiver = new StreamReceiverKeepPortable();
+
+                ldr.AllowOverwrite = true;
+
+                for (var i = 0; i < 100; i++)
+                    ldr.AddData(i, _grid.GetPortables().ToPortable<IPortableObject>(new PortableEntry {Val = i}));
+
+                ldr.Flush();
+
+                for (var i = 0; i < 100; i++)
+                    Assert.AreEqual(i + 1, cache.Get(i).Val);
+            }
+        }
+
+        /// <summary>
+        /// Gets the Ignite configuration.
+        /// </summary>
+        /// <param name="gridName">Grid name.</param>
+        private static IgniteConfigurationEx GetIgniteConfiguration(string gridName)
+        {
+            return new IgniteConfigurationEx
+            {
+                GridName = gridName,
+                SpringConfigUrl = "config\\native-client-test-cache.xml",
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                PortableConfiguration = new PortableConfiguration
+                {
+                    TypeConfigurations = new List<PortableTypeConfiguration>
+                    {
+                        new PortableTypeConfiguration(typeof (CacheTestKey)),
+                        new PortableTypeConfiguration(typeof (TestReferenceObject)),
+                        new PortableTypeConfiguration(typeof (StreamReceiverPortable)),
+                        new PortableTypeConfiguration(typeof (EntryProcessorPortable)),
+                        new PortableTypeConfiguration(typeof (PortableEntry))
+                    }
+                },
+                JvmOptions = TestUtils.TestJavaOptions().Concat(new[]
+                {
+                    "-Xms3096m",
+                    "-Xmx3096m",
+                    "-XX:+UseParNewGC",
+                    "-XX:+UseConcMarkSweepGC",
+                    "-XX:+UseTLAB",
+                    "-XX:NewSize=128m",
+                    "-XX:MaxNewSize=128m",
+                    "-XX:MaxTenuringThreshold=0",
+                    "-XX:SurvivorRatio=1024",
+                    "-XX:+UseCMSInitiatingOccupancyOnly",
+                    "-XX:CMSInitiatingOccupancyFraction=60"
+                }).ToArray()
+            };
+        }
+
+        /// <summary>
+        /// Test portable receiver.
+        /// </summary>
+        private class StreamReceiverPortable : IStreamReceiver<int, int>
+        {
+            /** <inheritdoc /> */
+            public void Receive(ICache<int, int> cache, ICollection<ICacheEntry<int, int>> entries)
+            {
+                cache.PutAll(entries.ToDictionary(x => x.Key, x => x.Value + 1));
+            }
+        }
+
+        /// <summary>
+        /// Test portable receiver.
+        /// </summary>
+        [Serializable]
+        private class StreamReceiverKeepPortable : IStreamReceiver<int, IPortableObject>
+        {
+            /** <inheritdoc /> */
+            public void Receive(ICache<int, IPortableObject> cache, ICollection<ICacheEntry<int, IPortableObject>> entries)
+            {
+                var portables = cache.Ignite.GetPortables();
+
+                cache.PutAll(entries.ToDictionary(x => x.Key, x =>
+                    portables.ToPortable<IPortableObject>(new PortableEntry
+                    {
+                        Val = x.Value.Deserialize<PortableEntry>().Val + 1
+                    })));
+            }
+        }
+
+        /// <summary>
+        /// Test serializable receiver.
+        /// </summary>
+        [Serializable]
+        private class StreamReceiverSerializable : IStreamReceiver<int, int>
+        {
+            /** <inheritdoc /> */
+            public void Receive(ICache<int, int> cache, ICollection<ICacheEntry<int, int>> entries)
+            {
+                cache.PutAll(entries.ToDictionary(x => x.Key, x => x.Value + 1));
+            }
+        }
+
+        /// <summary>
+        /// Test entry processor.
+        /// </summary>
+        [Serializable]
+        private class EntryProcessorSerializable : ICacheEntryProcessor<int, int, int, int>
+        {
+            /** <inheritdoc /> */
+            public int Process(IMutableCacheEntry<int, int> entry, int arg)
+            {
+                entry.Value = entry.Key + 1;
+                
+                return 0;
+            }
+        }
+
+        /// <summary>
+        /// Test entry processor.
+        /// </summary>
+        private class EntryProcessorPortable : ICacheEntryProcessor<int, int, int, int>, IPortableMarshalAware
+        {
+            /** <inheritdoc /> */
+            public int Process(IMutableCacheEntry<int, int> entry, int arg)
+            {
+                entry.Value = entry.Key + 1;
+                
+                return 0;
+            }
+
+            /** <inheritdoc /> */
+            public void WritePortable(IPortableWriter writer)
+            {
+                // No-op.
+            }
+
+            /** <inheritdoc /> */
+            public void ReadPortable(IPortableReader reader)
+            {
+                // No-op.
+            }
+        }
+
+        /// <summary>
+        /// Portablecache entry.
+        /// </summary>
+        private class PortableEntry
+        {
+            public int Val { get; set; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
new file mode 100644
index 0000000..aa103d4
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/EventsTest.cs
@@ -0,0 +1,961 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests
+{
+    using System;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Threading;
+    using System.Threading.Tasks;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Events;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Events;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Tests.Compute;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// <see cref="IEvents"/> tests.
+    /// </summary>
+    public class EventsTest
+    {
+        /** */
+        private IIgnite _grid1;
+
+        /** */
+        private IIgnite _grid2;
+
+        /** */
+        private IIgnite _grid3;
+
+        /** */
+        private IIgnite[] _grids;
+        
+        /** */
+        public static int IdGen;
+
+        [TestFixtureTearDown]
+        public void FixtureTearDown()
+        {
+            StopGrids();
+        }
+
+        /// <summary>
+        /// Executes before each test.
+        /// </summary>
+        [SetUp]
+        public void SetUp()
+        {
+            StartGrids();
+            EventsTestHelper.ListenResult = true;
+        }
+
+        /// <summary>
+        /// Executes after each test.
+        /// </summary>
+        [TearDown]
+        public virtual void TearDown()
+        {
+            try
+            {
+                TestUtils.AssertHandleRegistryIsEmpty(1000, _grid1, _grid2, _grid3);
+            }
+            catch (Exception)
+            {
+                // Restart grids to cleanup
+                StopGrids();
+
+                throw;
+            }
+            finally
+            {
+                EventsTestHelper.AssertFailures();
+
+                if (TestContext.CurrentContext.Test.Name.StartsWith("TestEventTypes"))
+                    StopGrids(); // clean events for other tests
+            }
+        }
+
+        /// <summary>
+        /// Tests enable/disable of event types.
+        /// </summary>
+        [Test]
+        public void TestEnableDisable()
+        {
+            var events = _grid1.GetEvents();
+
+            Assert.AreEqual(0, events.GetEnabledEvents().Length);
+
+            Assert.IsFalse(EventType.EvtsCache.Any(events.IsEnabled));
+
+            events.EnableLocal(EventType.EvtsCache);
+
+            Assert.AreEqual(EventType.EvtsCache, events.GetEnabledEvents());
+
+            Assert.IsTrue(EventType.EvtsCache.All(events.IsEnabled));
+
+            events.EnableLocal(EventType.EvtsTaskExecution);
+
+            events.DisableLocal(EventType.EvtsCache);
+
+            Assert.AreEqual(EventType.EvtsTaskExecution, events.GetEnabledEvents());
+        }
+
+        /// <summary>
+        /// Tests LocalListen.
+        /// </summary>
+        [Test]
+        public void TestLocalListen()
+        {
+            var events = _grid1.GetEvents();
+            var listener = EventsTestHelper.GetListener();
+            var eventType = EventType.EvtsTaskExecution;
+
+            events.EnableLocal(eventType);
+
+            events.LocalListen(listener, eventType);
+
+            CheckSend(3);  // 3 events per task * 3 grids
+
+            // Check unsubscription for specific event
+            events.StopLocalListen(listener, EventType.EvtTaskReduced);
+
+            CheckSend(2);
+
+            // Unsubscribe from all events
+            events.StopLocalListen(listener);
+
+            CheckNoEvent();
+
+            // Check unsubscription by filter
+            events.LocalListen(listener, EventType.EvtTaskReduced);
+
+            CheckSend();
+
+            EventsTestHelper.ListenResult = false;
+
+            CheckSend();  // one last event will be received for each listener
+
+            CheckNoEvent();
+        }
+
+        /// <summary>
+        /// Tests LocalListen.
+        /// </summary>
+        [Test]
+        [Ignore("IGNITE-879")]
+        public void TestLocalListenRepeatedSubscription()
+        {
+            var events = _grid1.GetEvents();
+            var listener = EventsTestHelper.GetListener();
+            var eventType = EventType.EvtsTaskExecution;
+
+            events.EnableLocal(eventType);
+
+            events.LocalListen(listener, eventType);
+
+            CheckSend(3);  // 3 events per task * 3 grids
+
+            events.LocalListen(listener, eventType);
+            events.LocalListen(listener, eventType);
+
+            CheckSend(9);
+
+            events.StopLocalListen(listener, eventType);
+
+            CheckSend(6);
+
+            events.StopLocalListen(listener, eventType);
+
+            CheckSend(3);
+            
+            events.StopLocalListen(listener, eventType);
+
+            CheckNoEvent();
+        }
+
+        /// <summary>
+        /// Tests all available event types/classes.
+        /// </summary>
+        [Test, TestCaseSource("TestCases")]
+        public void TestEventTypes(EventTestCase testCase)
+        {
+            var events = _grid1.GetEvents();
+
+            events.EnableLocal(testCase.EventType);
+
+            var listener = EventsTestHelper.GetListener();
+
+            events.LocalListen(listener, testCase.EventType);
+
+            EventsTestHelper.ClearReceived(testCase.EventCount);
+
+            testCase.GenerateEvent(_grid1);
+
+            EventsTestHelper.VerifyReceive(testCase.EventCount, testCase.EventObjectType, testCase.EventType);
+
+            if (testCase.VerifyEvents != null)
+                testCase.VerifyEvents(EventsTestHelper.ReceivedEvents.Reverse(), _grid1);
+
+            // Check stop
+            events.StopLocalListen(listener);
+
+            EventsTestHelper.ClearReceived(0);
+
+            testCase.GenerateEvent(_grid1);
+
+            Thread.Sleep(EventsTestHelper.Timeout);
+        }
+
+        /// <summary>
+        /// Test cases for TestEventTypes: type id + type + event generator.
+        /// </summary>
+        public IEnumerable<EventTestCase> TestCases
+        {
+            get
+            {
+                yield return new EventTestCase
+                {
+                    EventType = EventType.EvtsCache,
+                    EventObjectType = typeof (CacheEvent),
+                    GenerateEvent = g => g.GetCache<int, int>(null).Put(1, 1),
+                    VerifyEvents = (e, g) => VerifyCacheEvents(e, g),
+                    EventCount = 1
+                };
+
+                yield return new EventTestCase
+                {
+                    EventType = EventType.EvtsTaskExecution,
+                    EventObjectType = typeof (TaskEvent),
+                    GenerateEvent = g => GenerateTaskEvent(g),
+                    VerifyEvents = (e, g) => VerifyTaskEvents(e),
+                    EventCount = 3
+                };
+
+                yield return new EventTestCase
+                {
+                    EventType = EventType.EvtsJobExecution,
+                    EventObjectType = typeof (JobEvent),
+                    GenerateEvent = g => GenerateTaskEvent(g),
+                    EventCount = 9
+                };
+
+                yield return new EventTestCase
+                {
+                    EventType = new[] {EventType.EvtCacheQueryExecuted},
+                    EventObjectType = typeof (CacheQueryExecutedEvent),
+                    GenerateEvent = g => GenerateCacheQueryEvent(g),
+                    EventCount = 1
+                };
+
+                yield return new EventTestCase
+                {
+                    EventType = new[] { EventType.EvtCacheQueryObjectRead },
+                    EventObjectType = typeof (CacheQueryReadEvent),
+                    GenerateEvent = g => GenerateCacheQueryEvent(g),
+                    EventCount = 1
+                };
+            }
+        }
+
+        /// <summary>
+        /// Tests the LocalQuery.
+        /// </summary>
+        [Test]
+        public void TestLocalQuery()
+        {
+            var events = _grid1.GetEvents();
+
+            var eventType = EventType.EvtsTaskExecution;
+
+            events.EnableLocal(eventType);
+
+            var oldEvents = events.LocalQuery();
+
+            GenerateTaskEvent();
+
+            // "Except" works because of overridden equality
+            var qryResult = events.LocalQuery(eventType).Except(oldEvents).ToList();
+
+            Assert.AreEqual(3, qryResult.Count);
+        }
+
+        /// <summary>
+        /// Tests the WaitForLocal.
+        /// </summary>
+        [Test]
+        public void TestWaitForLocal([Values(true, false)] bool async)
+        {
+            var events = _grid1.GetEvents();
+
+            var timeout = TimeSpan.FromSeconds(3);
+
+            if (async)
+                events = events.WithAsync();
+
+            var eventType = EventType.EvtsTaskExecution;
+
+            events.EnableLocal(eventType);
+
+            Func<Func<IEvent>, Task<IEvent>> getWaitTask;
+
+            if (async)
+                getWaitTask = func =>
+                {
+                    Assert.IsNull(func());
+                    var task = events.GetFuture<IEvent>().ToTask();
+                    GenerateTaskEvent();
+                    return task;
+                };
+            else
+                getWaitTask = func =>
+                {
+                    var task = Task.Factory.StartNew(func);
+                    Thread.Sleep(500); // allow task to start and begin waiting for events
+                    GenerateTaskEvent();
+                    return task;
+                };
+
+            // No params
+            var waitTask = getWaitTask(() => events.WaitForLocal());
+
+            waitTask.Wait(timeout);
+
+            // Event types
+            waitTask = getWaitTask(() => events.WaitForLocal(EventType.EvtTaskReduced));
+
+            Assert.IsTrue(waitTask.Wait(timeout));
+            Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+            Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+
+            // Filter
+            waitTask = getWaitTask(() => events.WaitForLocal(
+                new EventFilter<IEvent>((g, e) => e.Type == EventType.EvtTaskReduced)));
+
+            Assert.IsTrue(waitTask.Wait(timeout));
+            Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+            Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+
+            // Filter & types
+            waitTask = getWaitTask(() => events.WaitForLocal(
+                new EventFilter<IEvent>((g, e) => e.Type == EventType.EvtTaskReduced), EventType.EvtTaskReduced));
+
+            Assert.IsTrue(waitTask.Wait(timeout));
+            Assert.IsInstanceOf(typeof(TaskEvent), waitTask.Result);
+            Assert.AreEqual(EventType.EvtTaskReduced, waitTask.Result.Type);
+        }
+
+        /// <summary>
+        /// Tests RemoteListen.
+        /// </summary>
+        [Test]
+        public void TestRemoteListen(
+            [Values(true, false)] bool async, 
+            [Values(true, false)] bool portable,
+            [Values(true, false)] bool autoUnsubscribe)
+        {
+            foreach (var g in _grids)
+            {
+                g.GetEvents().EnableLocal(EventType.EvtsJobExecution);
+                g.GetEvents().EnableLocal(EventType.EvtsTaskExecution);
+            }
+
+            var events = _grid1.GetEvents();
+
+            var expectedType = EventType.EvtJobStarted;
+
+            var remoteFilter = portable 
+                ?  (IEventFilter<IEvent>) new RemoteEventPortableFilter(expectedType) 
+                :  new RemoteEventFilter(expectedType);
+
+            var localListener = EventsTestHelper.GetListener();
+
+            if (async)
+                events = events.WithAsync();
+
+            var listenId = events.RemoteListen(localListener: localListener, remoteFilter: remoteFilter,
+                autoUnsubscribe: autoUnsubscribe);
+
+            if (async)
+                listenId = events.GetFuture<Guid>().Get();
+
+            CheckSend(3, typeof(JobEvent), expectedType);
+
+            _grid3.GetEvents().DisableLocal(EventType.EvtsJobExecution);
+
+            CheckSend(2, typeof(JobEvent), expectedType);
+
+            events.StopRemoteListen(listenId);
+
+            if (async)
+                events.GetFuture().Get();
+
+            CheckNoEvent();
+
+            // Check unsubscription with listener
+            events.RemoteListen(localListener: localListener, remoteFilter: remoteFilter,
+                autoUnsubscribe: autoUnsubscribe);
+
+            if (async)
+                events.GetFuture<Guid>().Get();
+
+            CheckSend(2, typeof(JobEvent), expectedType);
+
+            EventsTestHelper.ListenResult = false;
+
+            CheckSend(1, typeof(JobEvent), expectedType);  // one last event
+
+            CheckNoEvent();
+        }
+
+        /// <summary>
+        /// Tests RemoteQuery.
+        /// </summary>
+        [Test]
+        public void TestRemoteQuery([Values(true, false)] bool async)
+        {
+            foreach (var g in _grids)
+                g.GetEvents().EnableLocal(EventType.EvtsJobExecution);
+
+            var events = _grid1.GetEvents();
+
+            var eventFilter = new RemoteEventFilter(EventType.EvtJobStarted);
+
+            var oldEvents = events.RemoteQuery(eventFilter);
+
+            if (async)
+                events = events.WithAsync();
+
+            GenerateTaskEvent();
+
+            var remoteQuery = events.RemoteQuery(eventFilter, EventsTestHelper.Timeout, EventType.EvtsJobExecution);
+
+            if (async)
+            {
+                Assert.IsNull(remoteQuery);
+
+                remoteQuery = events.GetFuture<List<IEvent>>().Get().ToList();
+            }
+
+            var qryResult = remoteQuery.Except(oldEvents).Cast<JobEvent>().ToList();
+
+            Assert.AreEqual(_grids.Length, qryResult.Count);
+
+            Assert.IsTrue(qryResult.All(x => x.Type == EventType.EvtJobStarted));
+        }
+
+        /// <summary>
+        /// Tests serialization.
+        /// </summary>
+        [Test]
+        public void TestSerialization()
+        {
+            var grid = (Ignite) _grid1;
+            var comp = (Impl.Compute.Compute) grid.GetCluster().ForLocal().GetCompute();
+            var locNode = grid.GetCluster().GetLocalNode();
+
+            var expectedGuid = Guid.Parse("00000000-0000-0001-0000-000000000002");
+            var expectedGridGuid = new IgniteGuid(expectedGuid, 3);
+
+            using (var inStream = IgniteManager.Memory.Allocate().Stream())
+            {
+                var result = comp.ExecuteJavaTask<bool>("org.apache.ignite.platform.PlatformEventsWriteEventTask",
+                    inStream.MemoryPointer);
+
+                Assert.IsTrue(result);
+
+                inStream.SynchronizeInput();
+
+                var reader = grid.Marshaller.StartUnmarshal(inStream);
+
+                var cacheEvent = EventReader.Read<CacheEvent>(reader);
+                CheckEventBase(cacheEvent);
+                Assert.AreEqual("cacheName", cacheEvent.CacheName);
+                Assert.AreEqual(locNode, cacheEvent.EventNode);
+                Assert.AreEqual(1, cacheEvent.Partition);
+                Assert.AreEqual(true, cacheEvent.IsNear);
+                Assert.AreEqual(2, cacheEvent.Key);
+                Assert.AreEqual(expectedGridGuid, cacheEvent.Xid);
+                Assert.AreEqual(3, cacheEvent.LockId);
+                Assert.AreEqual(4, cacheEvent.NewValue);
+                Assert.AreEqual(true, cacheEvent.HasNewValue);
+                Assert.AreEqual(5, cacheEvent.OldValue);
+                Assert.AreEqual(true, cacheEvent.HasOldValue);
+                Assert.AreEqual(expectedGuid, cacheEvent.SubjectId);
+                Assert.AreEqual("cloClsName", cacheEvent.ClosureClassName);
+                Assert.AreEqual("taskName", cacheEvent.TaskName);
+
+                var qryExecEvent = EventReader.Read<CacheQueryExecutedEvent>(reader);
+                CheckEventBase(qryExecEvent);
+                Assert.AreEqual("qryType", qryExecEvent.QueryType);
+                Assert.AreEqual("cacheName", qryExecEvent.CacheName);
+                Assert.AreEqual("clsName", qryExecEvent.ClassName);
+                Assert.AreEqual("clause", qryExecEvent.Clause);
+                Assert.AreEqual(expectedGuid, qryExecEvent.SubjectId);
+                Assert.AreEqual("taskName", qryExecEvent.TaskName);
+
+                var qryReadEvent = EventReader.Read<CacheQueryReadEvent>(reader);
+                CheckEventBase(qryReadEvent);
+                Assert.AreEqual("qryType", qryReadEvent.QueryType);
+                Assert.AreEqual("cacheName", qryReadEvent.CacheName);
+                Assert.AreEqual("clsName", qryReadEvent.ClassName);
+                Assert.AreEqual("clause", qryReadEvent.Clause);
+                Assert.AreEqual(expectedGuid, qryReadEvent.SubjectId);
+                Assert.AreEqual("taskName", qryReadEvent.TaskName);
+                Assert.AreEqual(1, qryReadEvent.Key);
+                Assert.AreEqual(2, qryReadEvent.Value);
+                Assert.AreEqual(3, qryReadEvent.OldValue);
+                Assert.AreEqual(4, qryReadEvent.Row);
+
+                var cacheRebalancingEvent = EventReader.Read<CacheRebalancingEvent>(reader);
+                CheckEventBase(cacheRebalancingEvent);
+                Assert.AreEqual("cacheName", cacheRebalancingEvent.CacheName);
+                Assert.AreEqual(1, cacheRebalancingEvent.Partition);
+                Assert.AreEqual(locNode, cacheRebalancingEvent.DiscoveryNode);
+                Assert.AreEqual(2, cacheRebalancingEvent.DiscoveryEventType);
+                Assert.AreEqual(3, cacheRebalancingEvent.DiscoveryTimestamp);
+                
+                var checkpointEvent = EventReader.Read<CheckpointEvent>(reader);
+                CheckEventBase(checkpointEvent);
+                Assert.AreEqual("cpKey", checkpointEvent.Key);
+                
+                var discoEvent = EventReader.Read<DiscoveryEvent>(reader);
+                CheckEventBase(discoEvent);
+                Assert.AreEqual(grid.TopologyVersion, discoEvent.TopologyVersion);
+                Assert.AreEqual(grid.GetNodes(), discoEvent.TopologyNodes);
+
+                var jobEvent = EventReader.Read<JobEvent>(reader);
+                CheckEventBase(jobEvent);
+                Assert.AreEqual(expectedGridGuid, jobEvent.JobId);
+                Assert.AreEqual("taskClsName", jobEvent.TaskClassName);
+                Assert.AreEqual("taskName", jobEvent.TaskName);
+                Assert.AreEqual(locNode, jobEvent.TaskNode);
+                Assert.AreEqual(expectedGridGuid, jobEvent.TaskSessionId);
+                Assert.AreEqual(expectedGuid, jobEvent.TaskSubjectId);
+
+                var spaceEvent = EventReader.Read<SwapSpaceEvent>(reader);
+                CheckEventBase(spaceEvent);
+                Assert.AreEqual("space", spaceEvent.Space);
+
+                var taskEvent = EventReader.Read<TaskEvent>(reader);
+                CheckEventBase(taskEvent);
+                Assert.AreEqual(true,taskEvent.Internal);
+                Assert.AreEqual(expectedGuid, taskEvent.SubjectId);
+                Assert.AreEqual("taskClsName", taskEvent.TaskClassName);
+                Assert.AreEqual("taskName", taskEvent.TaskName);
+                Assert.AreEqual(expectedGridGuid, taskEvent.TaskSessionId);
+            }
+        }
+
+        /// <summary>
+        /// Checks base event fields serialization.
+        /// </summary>
+        /// <param name="evt">The evt.</param>
+        private void CheckEventBase(IEvent evt)
+        {
+            var locNode = _grid1.GetCluster().GetLocalNode();
+
+            Assert.AreEqual(locNode, evt.Node);
+            Assert.AreEqual("msg", evt.Message);
+            Assert.AreEqual(EventType.EvtSwapSpaceCleared, evt.Type);
+            Assert.IsNotNullOrEmpty(evt.Name);
+            Assert.AreNotEqual(Guid.Empty, evt.Id.GlobalId);
+            Assert.IsTrue((evt.TimeStamp - DateTime.Now).TotalSeconds < 10);
+        }
+
+        /// <summary>
+        /// Sends events in various ways and verifies correct receive.
+        /// </summary>
+        /// <param name="repeat">Expected event count multiplier.</param>
+        /// <param name="eventObjectType">Expected event object type.</param>
+        /// <param name="eventType">Type of the event.</param>
+        private void CheckSend(int repeat = 1, Type eventObjectType = null, params int[] eventType)
+        {
+            EventsTestHelper.ClearReceived(repeat);
+
+            GenerateTaskEvent();
+
+            EventsTestHelper.VerifyReceive(repeat, eventObjectType ?? typeof (TaskEvent),
+                eventType.Any() ? eventType : EventType.EvtsTaskExecution);
+        }
+
+        /// <summary>
+        /// Checks that no event has arrived.
+        /// </summary>
+        private void CheckNoEvent()
+        {
+            // this will result in an exception in case of a event
+            EventsTestHelper.ClearReceived(0);
+
+            GenerateTaskEvent();
+
+            Thread.Sleep(EventsTestHelper.Timeout);
+
+            EventsTestHelper.AssertFailures();
+        }
+
+        /// <summary>
+        /// Gets the Ignite configuration.
+        /// </summary>
+        private static IgniteConfiguration Configuration(string springConfigUrl)
+        {
+            return new IgniteConfiguration
+            {
+                SpringConfigUrl = springConfigUrl,
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                JvmOptions = TestUtils.TestJavaOptions(),
+                PortableConfiguration = new PortableConfiguration
+                {
+                    TypeConfigurations = new List<PortableTypeConfiguration>
+                    {
+                        new PortableTypeConfiguration(typeof (RemoteEventPortableFilter))
+                    }
+                }
+            };
+        }
+
+        /// <summary>
+        /// Generates the task event.
+        /// </summary>
+        private void GenerateTaskEvent(IIgnite grid = null)
+        {
+            (grid ?? _grid1).GetCompute().Broadcast(new ComputeAction());
+        }
+
+        /// <summary>
+        /// Verifies the task events.
+        /// </summary>
+        private static void VerifyTaskEvents(IEnumerable<IEvent> events)
+        {
+            var e = events.Cast<TaskEvent>().ToArray();
+
+            // started, reduced, finished
+            Assert.AreEqual(
+                new[] {EventType.EvtTaskStarted, EventType.EvtTaskReduced, EventType.EvtTaskFinished},
+                e.Select(x => x.Type).ToArray());
+        }
+
+        /// <summary>
+        /// Generates the cache query event.
+        /// </summary>
+        private static void GenerateCacheQueryEvent(IIgnite g)
+        {
+            var cache = g.GetCache<int, int>(null);
+
+            cache.Clear();
+
+            cache.Put(1, 1);
+
+            cache.Query(new ScanQuery<int, int>()).GetAll();
+        }
+
+        /// <summary>
+        /// Verifies the cache events.
+        /// </summary>
+        private static void VerifyCacheEvents(IEnumerable<IEvent> events, IIgnite grid)
+        {
+            var e = events.Cast<CacheEvent>().ToArray();
+
+            foreach (var cacheEvent in e)
+            {
+                Assert.AreEqual(null, cacheEvent.CacheName);
+                Assert.AreEqual(null, cacheEvent.ClosureClassName);
+                Assert.AreEqual(null, cacheEvent.TaskName);
+                Assert.AreEqual(grid.GetCluster().GetLocalNode(), cacheEvent.EventNode);
+                Assert.AreEqual(grid.GetCluster().GetLocalNode(), cacheEvent.Node);
+
+                Assert.AreEqual(false, cacheEvent.HasOldValue);
+                Assert.AreEqual(null, cacheEvent.OldValue);
+
+                if (cacheEvent.Type == EventType.EvtCacheObjectPut)
+                {
+                    Assert.AreEqual(true, cacheEvent.HasNewValue);
+                    Assert.AreEqual(1, cacheEvent.NewValue);
+                }
+                else if (cacheEvent.Type == EventType.EvtCacheEntryCreated)
+                {
+                    Assert.AreEqual(false, cacheEvent.HasNewValue);
+                    Assert.AreEqual(null, cacheEvent.NewValue);
+                }
+                else
+                {
+                    Assert.Fail("Unexpected event type");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Starts the grids.
+        /// </summary>
+        private void StartGrids()
+        {
+            if (_grid1 != null)
+                return;
+
+            _grid1 = Ignition.Start(Configuration("config\\compute\\compute-grid1.xml"));
+            _grid2 = Ignition.Start(Configuration("config\\compute\\compute-grid2.xml"));
+            _grid3 = Ignition.Start(Configuration("config\\compute\\compute-grid3.xml"));
+
+            _grids = new[] {_grid1, _grid2, _grid3};
+        }
+
+        /// <summary>
+        /// Stops the grids.
+        /// </summary>
+        private void StopGrids()
+        {
+            _grid1 = _grid2 = _grid3 = null;
+            _grids = null;
+            
+            Ignition.StopAll(true);
+        }
+    }
+
+    /// <summary>
+    /// Event test helper class.
+    /// </summary>
+    [Serializable]
+    public static class EventsTestHelper
+    {
+        /** */
+        public static readonly ConcurrentStack<IEvent> ReceivedEvents = new ConcurrentStack<IEvent>();
+        
+        /** */
+        public static readonly ConcurrentStack<string> Failures = new ConcurrentStack<string>();
+
+        /** */
+        public static readonly CountdownEvent ReceivedEvent = new CountdownEvent(0);
+
+        /** */
+        public static readonly ConcurrentStack<Guid> LastNodeIds = new ConcurrentStack<Guid>();
+
+        /** */
+        public static volatile bool ListenResult = true;
+
+        /** */
+        public static readonly TimeSpan Timeout = TimeSpan.FromMilliseconds(800);
+
+        /// <summary>
+        /// Clears received event information.
+        /// </summary>
+        /// <param name="expectedCount">The expected count of events to be received.</param>
+        public static void ClearReceived(int expectedCount)
+        {
+            ReceivedEvents.Clear();
+            ReceivedEvent.Reset(expectedCount);
+            LastNodeIds.Clear();
+        }
+
+        /// <summary>
+        /// Verifies received events against events events.
+        /// </summary>
+        public static void VerifyReceive(int count, Type eventObjectType, params int[] eventTypes)
+        {
+            // check if expected event count has been received; Wait returns false if there were none.
+            Assert.IsTrue(ReceivedEvent.Wait(Timeout), 
+                "Failed to receive expected number of events. Remaining count: " + ReceivedEvent.CurrentCount);
+            
+            Assert.AreEqual(count, ReceivedEvents.Count);
+
+            Assert.IsTrue(ReceivedEvents.All(x => x.GetType() == eventObjectType));
+
+            Assert.IsTrue(ReceivedEvents.All(x => eventTypes.Contains(x.Type)));
+
+            AssertFailures();
+        }
+
+        /// <summary>
+        /// Gets the event listener.
+        /// </summary>
+        /// <returns>New instance of event listener.</returns>
+        public static IEventFilter<IEvent> GetListener()
+        {
+            return new EventFilter<IEvent>(Listen);
+        }
+
+        /// <summary>
+        /// Combines accumulated failures and throws an assertion, if there are any.
+        /// Clears accumulated failures.
+        /// </summary>
+        public static void AssertFailures()
+        {
+            try
+            {
+                if (Failures.Any())
+                    Assert.Fail(Failures.Reverse().Aggregate((x, y) => string.Format("{0}\n{1}", x, y)));
+            }
+            finally 
+            {
+                Failures.Clear();
+            }
+        }
+
+        /// <summary>
+        /// Listen method.
+        /// </summary>
+        /// <param name="id">Originating node ID.</param>
+        /// <param name="evt">Event.</param>
+        private static bool Listen(Guid id, IEvent evt)
+        {
+            try
+            {
+                LastNodeIds.Push(id);
+                ReceivedEvents.Push(evt);
+
+                ReceivedEvent.Signal();
+                
+                return ListenResult;
+            }
+            catch (Exception ex)
+            {
+                // When executed on remote nodes, these exceptions will not go to sender, 
+                // so we have to accumulate them.
+                Failures.Push(string.Format("Exception in Listen (msg: {0}, id: {1}): {2}", evt, id, ex));
+                throw;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Test event filter.
+    /// </summary>
+    [Serializable]
+    public class EventFilter<T> : IEventFilter<T> where T : IEvent
+    {
+        /** */
+        private readonly Func<Guid, T, bool> _invoke;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RemoteListenEventFilter"/> class.
+        /// </summary>
+        /// <param name="invoke">The invoke delegate.</param>
+        public EventFilter(Func<Guid, T, bool> invoke)
+        {
+            _invoke = invoke;
+        }
+
+        /** <inheritdoc /> */
+        bool IEventFilter<T>.Invoke(Guid nodeId, T evt)
+        {
+            return _invoke(nodeId, evt);
+        }
+
+        /** <inheritdoc /> */
+        public bool Invoke(Guid nodeId, T evt)
+        {
+            throw new Exception("Invalid method");
+        }
+    }
+
+    /// <summary>
+    /// Remote event filter.
+    /// </summary>
+    [Serializable]
+    public class RemoteEventFilter : IEventFilter<IEvent>
+    {
+        /** */
+        private readonly int _type;
+
+        public RemoteEventFilter(int type)
+        {
+            _type = type;
+        }
+
+        /** <inheritdoc /> */
+        public bool Invoke(Guid nodeId, IEvent evt)
+        {
+            return evt.Type == _type;
+        }
+    }
+
+    /// <summary>
+    /// Portable remote event filter.
+    /// </summary>
+    public class RemoteEventPortableFilter : IEventFilter<IEvent>, IPortableMarshalAware
+    {
+        /** */
+        private int _type;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RemoteEventPortableFilter"/> class.
+        /// </summary>
+        /// <param name="type">The event type.</param>
+        public RemoteEventPortableFilter(int type)
+        {
+            _type = type;
+        }
+
+        /** <inheritdoc /> */
+        public bool Invoke(Guid nodeId, IEvent evt)
+        {
+            return evt.Type == _type;
+        }
+
+        /** <inheritdoc /> */
+        public void WritePortable(IPortableWriter writer)
+        {
+            writer.RawWriter().WriteInt(_type);
+        }
+
+        /** <inheritdoc /> */
+        public void ReadPortable(IPortableReader reader)
+        {
+            _type = reader.RawReader().ReadInt();
+        }
+    }
+
+    /// <summary>
+    /// Event test case.
+    /// </summary>
+    public class EventTestCase
+    {
+        /// <summary>
+        /// Gets or sets the type of the event.
+        /// </summary>
+        public int[] EventType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the type of the event object.
+        /// </summary>
+        public Type EventObjectType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the generate event action.
+        /// </summary>
+        public Action<IIgnite> GenerateEvent { get; set; }
+
+        /// <summary>
+        /// Gets or sets the verify events action.
+        /// </summary>
+        public Action<IEnumerable<IEvent>, IIgnite> VerifyEvents { get; set; }
+
+        /// <summary>
+        /// Gets or sets the event count.
+        /// </summary>
+        public int EventCount { get; set; }
+
+        /** <inheritdoc /> */
+        public override string ToString()
+        {
+            return EventObjectType.ToString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/65bb69da/modules/platform/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
new file mode 100644
index 0000000..edb04cb
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core.Tests/Examples/Example.cs
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Examples
+{
+    using System;
+    using System.Collections.Generic;
+    using System.IO;
+    using System.Linq;
+    using System.Text.RegularExpressions;
+    using Apache.Ignite.Examples.Compute;
+    using Apache.Ignite.ExamplesDll.Compute;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Represents an Example to be tested.
+    /// </summary>
+    public class Example
+    {
+        /** All examples */
+        private static readonly Example[] Examples = GetExamples().ToArray();
+
+        /** Execute action */
+        private Action _runAction;
+
+        /** Config url */
+        public string SpringConfigUrl { get; private set; }
+
+        /** Source path */
+        public string SourceFilePath { get; private set; }
+
+        /** Dll load flag */
+        public bool NeedsTestDll { get; private set; }
+
+        /** Name */
+        public string Name { get; private set; }
+
+        /// <summary>
+        /// Runs this example.
+        /// </summary>
+        public void Run()
+        {
+            try
+            {
+                _runAction();
+            }
+            catch (InvalidOperationException ex)
+            {
+                // Each example has a ReadKey at the end, which throws an exception in test environment.
+                if (ex.Message != "Cannot read keys when either application does not have a console or " +
+                    "when console input has been redirected from a file. Try Console.Read.")
+                    throw;
+            }
+        }
+
+        /// <summary>
+        /// Gets all examples.
+        /// </summary>
+        public static IEnumerable<Example> All
+        {
+            get { return Examples; }
+        }
+
+        /// <summary>
+        /// Gets all examples.
+        /// </summary>
+        private static IEnumerable<Example> GetExamples()
+        {
+            var examplesAsm = typeof (ClosureExample).Assembly;
+
+            var sourceFiles = Directory.GetFiles(PathUtil.ExamplesSourcePath, "*.cs", SearchOption.AllDirectories);
+
+            Assert.IsTrue(sourceFiles.Any());
+
+            var types = examplesAsm.GetTypes().Where(x => x.GetMethod("Main") != null).ToArray();
+
+            Assert.IsTrue(types.Any());
+
+            var examplesDllName = typeof(AverageSalaryJob).Assembly.GetName().Name;
+
+            foreach (var type in types)
+            {
+                var sourceFile = sourceFiles.Single(x => x.EndsWith(string.Format("\\{0}.cs", type.Name)));
+
+                var sourceCode = File.ReadAllText(sourceFile);
+
+                yield return new Example
+                {
+                    SourceFilePath = sourceFile,
+                    SpringConfigUrl = PathUtil.GetFullConfigPath(GetSpringConfigUrl(sourceCode)),
+                    NeedsTestDll = sourceCode.Contains(examplesDllName),
+                    _runAction = GetRunAction(type),
+                    Name = type.Name
+                };
+            }
+        }
+
+        /// <summary>
+        /// Gets the run action.
+        /// </summary>
+        private static Action GetRunAction(Type type)
+        {
+            return (Action) Delegate.CreateDelegate(typeof (Action), type.GetMethod("Main"));
+        }
+
+        /// <summary>
+        /// Gets the spring configuration URL.
+        /// </summary>
+        private static string GetSpringConfigUrl(string code)
+        {
+            var match = Regex.Match(code, "-springConfigUrl=(.*?.xml)");
+
+            return match.Success ? match.Groups[1].Value : null;
+        }
+
+        /** <inheritdoc /> */
+        public override string ToString()
+        {
+            // This will be displayed in TeamCity and R# test runner
+            return Name;
+        }
+    }
+}
\ No newline at end of file