IGNITE-16869 Remove outdated spring data extensions with upgrading spring-core dependency (#120)

diff --git a/modules/aws-ext/pom.xml b/modules/aws-ext/pom.xml
index e6452ff..d31563b 100644
--- a/modules/aws-ext/pom.xml
+++ b/modules/aws-ext/pom.xml
@@ -33,7 +33,6 @@
     <url>https://ignite.apache.org</url>
 
     <properties>
-        <spring.version>5.3.8</spring.version>
         <aws.sdk.version>1.11.75</aws.sdk.version>
         <aws.encryption.sdk.version>1.3.2</aws.encryption.sdk.version>
         <bouncycastle.version>1.69</bouncycastle.version>
@@ -172,7 +171,7 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-beans</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
@@ -185,14 +184,14 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/modules/azure-ext/pom.xml b/modules/azure-ext/pom.xml
index a5318ac..5112e4f 100644
--- a/modules/azure-ext/pom.xml
+++ b/modules/azure-ext/pom.xml
@@ -32,7 +32,6 @@
     <url>https://ignite.apache.org</url>
 
     <properties>
-        <spring.version>5.3.8</spring.version>
         <netty.version>4.1.66.Final</netty.version>
     </properties>
 
@@ -359,21 +358,21 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-beans</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/modules/gce-ext/pom.xml b/modules/gce-ext/pom.xml
index 41e2ae4..5b03a0e 100644
--- a/modules/gce-ext/pom.xml
+++ b/modules/gce-ext/pom.xml
@@ -31,10 +31,6 @@
     <version>1.0.0-SNAPSHOT</version>
     <url>https://ignite.apache.org</url>
 
-    <properties>
-        <spring.version>5.3.8</spring.version>
-    </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.apache.ignite</groupId>
@@ -91,21 +87,21 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-beans</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
diff --git a/modules/spring-boot-autoconfigure-ext/pom.xml b/modules/spring-boot-autoconfigure-ext/pom.xml
index 8ad0018..d0a56d4 100644
--- a/modules/spring-boot-autoconfigure-ext/pom.xml
+++ b/modules/spring-boot-autoconfigure-ext/pom.xml
@@ -58,22 +58,22 @@
 
         <dependency>
             <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.2-ext</artifactId>
-            <version>${ignite-spring-data-2.2-ext.version}</version>
+            <artifactId>ignite-spring-data-ext</artifactId>
+            <version>${ignite-spring-data-ext.version}</version>
             <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.2.version}</version>
+            <version>${spring.data.version}</version>
             <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-tx</artifactId>
-            <version>${spring-5.2.version}</version>
+            <version>${spring.version}</version>
             <optional>true</optional>
         </dependency>
 
diff --git a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
index 8829d3a..e787a41 100644
--- a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
+++ b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoryAutoConfiguration.java
@@ -18,10 +18,10 @@
 package org.apache.ignite.springframework.boot.autoconfigure;
 
 import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
 import org.apache.ignite.springframework.boot.autoconfigure.data.IgniteRepositoriesAutoConfigurationRegistrar;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
index 24b0992..d24b389 100644
--- a/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
+++ b/modules/spring-boot-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
@@ -18,8 +18,8 @@
 package org.apache.ignite.springframework.boot.autoconfigure.data;
 
 import java.lang.annotation.Annotation;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
 import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
 import org.springframework.data.repository.config.RepositoryConfigurationExtension;
diff --git a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
index e1e86ca..66e71fb 100644
--- a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
+++ b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteRepositoriesAutoconfigureTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.ignite.springframework.boot.autoconfigure;
 
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
 import org.apache.ignite.springframework.boot.autoconfigure.misc.DefaultTestConfigutation;
 import org.apache.ignite.springframework.boot.autoconfigure.misc.ObjectRepository;
 import org.junit.jupiter.api.Test;
diff --git a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
index 0e68033..fcd6576 100644
--- a/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
+++ b/modules/spring-boot-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
@@ -17,8 +17,8 @@
 
 package org.apache.ignite.springframework.boot.autoconfigure.misc;
 
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 
 /**
  * Test repository.
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml b/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
index 4188bfd..0d338a4 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/pom.xml
@@ -59,22 +59,22 @@
 
         <dependency>
             <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.2-ext</artifactId>
-            <version>${ignite-spring-data-2.2-ext.version}</version>
+            <artifactId>ignite-spring-data-ext</artifactId>
+            <version>${ignite-spring-data-ext.version}</version>
             <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.2.version}</version>
+            <version>${spring.data.version}</version>
             <optional>true</optional>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-tx</artifactId>
-            <version>${spring-5.2.version}</version>
+            <version>${spring.version}</version>
             <optional>true</optional>
         </dependency>
 
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
index 1f54feb..ac42fa0 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoryAutoConfiguration.java
@@ -18,10 +18,10 @@
 package org.apache.ignite.springframework.boot.autoconfigure;
 
 import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
 import org.apache.ignite.springframework.boot.autoconfigure.data.IgniteRepositoriesAutoConfigurationRegistrar;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
index 24b0992..d24b389 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/main/java/org/apache/ignite/springframework/boot/autoconfigure/data/IgniteRepositoriesAutoConfigurationRegistrar.java
@@ -18,8 +18,8 @@
 package org.apache.ignite.springframework.boot.autoconfigure.data;
 
 import java.lang.annotation.Annotation;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.IgniteRepositoryConfigurationExtension;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.IgniteRepositoryConfigurationExtension;
 import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
 import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
 import org.springframework.data.repository.config.RepositoryConfigurationExtension;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
index 1cb58cc..4fae8f2 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/IgniteClientRepositoriesAutoconfigureTest.java
@@ -21,7 +21,7 @@
 import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.ClientConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
 import org.apache.ignite.springframework.boot.autoconfigure.misc.ObjectRepository;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
index 0e68033..fcd6576 100644
--- a/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
+++ b/modules/spring-boot-thin-client-autoconfigure-ext/src/test/java/org/apache/ignite/springframework/boot/autoconfigure/misc/ObjectRepository.java
@@ -17,8 +17,8 @@
 
 package org.apache.ignite.springframework.boot.autoconfigure.misc;
 
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 
 /**
  * Test repository.
diff --git a/modules/spring-data-2.0-ext/README.txt b/modules/spring-data-2.0-ext/README.txt
deleted file mode 100644
index b3d117b..0000000
--- a/modules/spring-data-2.0-ext/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Apache Ignite Spring Module
----------------------------
-
-Apache Ignite Spring Data 2.0 extension provides an integration with Spring Data 2.0 framework.
-
-Main features:
-
-- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
-- Supports query tuning parameters in @Query annotation
-- Supports projections
-- Supports Page and Stream responses
-- Supports Sql Fields Query resultset transformation into the domain entity
-- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
-- Supports advanced parameter binding and SpEL expressions into SQL queries:
-- Template variables:
-    - #entityName - the simple class name of the domain entity
-- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
-- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
-- Supports SpEL expressions into Text queries (TextQuery).
-
-Importing Spring Data 2.0 extension In Maven Project
-----------------------------------------
-
-If you are using Maven to manage dependencies of your project, you can add Spring Data 2.0 extension
-dependency like this (replace '${ignite-spring-data-2.0-ext.version}' with actual version of Ignite Spring Data 2.0
-extension you are interested in):
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
-                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    ...
-    <dependencies>
-        ...
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.0-ext</artifactId>
-            <version>${ignite-spring-data-2.0-ext.version}</version>
-        </dependency>
-        ...
-    </dependencies>
-    ...
-</project>
diff --git a/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml b/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml
deleted file mode 100644
index 4f51c12..0000000
--- a/modules/spring-data-2.0-ext/examples/config/example-spring-data.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?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.
--->
-
-<!--
-    Ignite Spring configuration file to startup Ignite cache.
-
-    This file demonstrates how to configure cache using Spring. Provided cache
-    will be created on node startup.
-
-    Use this configuration file when running Spring Data examples.
-
-    When starting a standalone node, you need to execute the following command:
-    {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-2.0/examples/config/example-spring-data.xml
-
-    When starting Ignite from Java IDE, pass path to this file to Ignition:
-    Ignition.start("modules/spring-data-2.0/examples/config/example-spring-data.xml");
--->
-<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">
-    <!-- Imports default Ignite configuration -->
-    <import resource="example-default.xml"/>
-
-    <bean parent="ignite.cfg">
-        <property name="igniteInstanceName" value="springDataNode" />
-
-        <property name="cacheConfiguration">
-            <list>
-                <bean class="org.apache.ignite.configuration.CacheConfiguration">
-                    <!--
-                        Apache Ignite uses an IgniteRepository extension which inherits from Spring Data's CrudRepository.
-                        The SQL grid is also enabled to aceess Spring Data repository. The @RepositoryConfig annotation
-                        maps the PersonRepository to an Ignite's cache named "PersonCache".
-                    -->
-                    <property name="name" value="PersonCache"/>
-                    <property name="indexedTypes">
-                        <list>
-                            <value>java.lang.Long</value>
-                            <value>org.apache.ignite.springdata20.examples.model.Person</value>
-                        </list>
-                    </property>
-                </bean>
-            </list>
-        </property>
-    </bean>
-</beans>
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java
deleted file mode 100644
index e04a50a..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/IgniteClientSpringApplicationConfiguration.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.configuration.ClientConnectorConfiguration.DFLT_PORT;
-
-/**
- * Example of Spring application configuration that represents beans required to configure Spring Data repository access
- * to an Ignite cluster through the thin client.
- *
- * Note that both Ignite thin client and Ignite node approaches of Ignite cluster access configuration uses the same API.
- * Ignite Spring Data integration automatically recognizes the type of provided bean and use the appropriate
- * cluster connection.
- *
- * @see SpringApplicationConfiguration
- */
-@Configuration
-@EnableIgniteRepositories
-public class IgniteClientSpringApplicationConfiguration {
-    /**
-     * Creates Apache Ignite thin client instance bean which will be used for accessing the Ignite cluster.
-     * Note, that the name of the current bean must match value of {@link RepositoryConfig#igniteInstance}
-     * property that {@link PersonRepository} is marked with. In this particular case, the default value of
-     * {@link RepositoryConfig#igniteInstance} property is used.
-     */
-    @Bean
-    public IgniteClient igniteInstance() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + DFLT_PORT));
-    }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java
deleted file mode 100644
index 2e0a729..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/PersonRepository.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.examples.model.Person;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-
-/**
- * Apache Ignite Spring Data repository backed by Ignite Person's cache.
- * </p>
- * To link the repository with an Ignite cache use {@link RepositoryConfig#cacheName()} annotation's parameter.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Long> {
-    /**
-     * Gets all the persons with the given name.
-     * @param name Person name.
-     * @return A list of Persons with the given first name.
-     */
-    public List<Person> findByFirstName(String name);
-
-    /**
-     * Returns top Person with the specified surname.
-     * @param name Person surname.
-     * @return Person that satisfy the query.
-     */
-    public Cache.Entry<Long, Person> findTopByLastNameLike(String name);
-
-    /**
-     * Getting ids of all the Person satisfying the custom query from {@link Query} annotation.
-     *
-     * @param orgId Query parameter.
-     * @param pageable Pageable interface.
-     * @return A list of Persons' ids.
-     */
-    @Query("SELECT id FROM Person WHERE orgId > ?")
-    public List<Long> selectId(long orgId, Pageable pageable);
-}
-
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java
deleted file mode 100644
index 15ded04..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringApplicationConfiguration.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Every {@link IgniteRepository} is bound to a specific Apache Ignite that it communicates to in order to mutate and
- * read data via Spring Data API. To pass an instance of Apache Ignite cache to an {@link IgniteRepository} it's
- * required to initialize {@link IgniteRepositoryFactoryBean} with one of the following:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
- * <ul/>
- * In this example the first approach is utilized.
- */
-@Configuration
-@EnableIgniteRepositories
-public class SpringApplicationConfiguration {
-    /**
-     * Creating Apache Ignite instance bean. A bean will be passed to {@link IgniteRepositoryFactoryBean} to initialize
-     * all Ignite based Spring Data repositories and connect to a cluster.
-     */
-    @Bean
-    public Ignite igniteInstance() {
-        return Ignition.start("modules/spring-data-2.0-ext/examples/config/example-spring-data.xml");
-    }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java
deleted file mode 100644
index 325dd54..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/SpringDataExample.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.TreeMap;
-import javax.cache.Cache;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.examples.model.Person;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-
-/**
- * The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
- *
- * Additional cluster nodes can be started with special configuration file which
- * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data-2.0/examples/config/example-spring-data.xml'}.
- */
-public class SpringDataExample {
-    /** Spring Application Context. */
-    private static AnnotationConfigApplicationContext ctx;
-
-    /** Ignite Spring Data repository. */
-    private static PersonRepository repo;
-
-    /**
-     * Execute examples involving both approaches to configure Spring Data repository access to an Ignite cluster:
-     *      through Ignite thin client and through Ignite node.
-     * @param args Command line arguments, none required.
-     */
-    public static void main(String[] args) {
-        try (Ignite ignored = startIgniteNode()) {
-            // Ignite node instance is used to configure access to the Ignite cluster.
-            doSpringDataExample(SpringApplicationConfiguration.class);
-
-            // Ignite thin client instance is used to configure access to the Ignite cluster.
-            doSpringDataExample(IgniteClientSpringApplicationConfiguration.class);
-        }
-    }
-
-    /** Starts an Ignite node that simulates an Ignite cluster to which Spring Data repository will perform access. */
-    private static Ignite startIgniteNode() {
-        IgniteConfiguration cfg = new IgniteConfiguration()
-            .setPeerClassLoadingEnabled(true)
-            .setCacheConfiguration(new CacheConfiguration<Long, Person>("PersonCache")
-                .setIndexedTypes(Long.class, Person.class));
-
-        return Ignition.start(cfg);
-    }
-
-    /**
-     * Performs basic Spring Data repository operation.
-     *
-     * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
-     */
-    private static void doSpringDataExample(Class<?> springAppCfg) {
-        igniteSpringDataInit(springAppCfg);
-
-        populateRepository();
-
-        findPersons();
-
-        queryRepository();
-
-        System.out.println("\n>>> Cleaning out the repository...");
-
-        repo.deleteAll();
-
-        System.out.println("\n>>> Repository size: " + repo.count());
-
-        // Destroying the context.
-        ctx.destroy();
-    }
-
-    /**
-     * Initializes Spring Data and Ignite repositories.
-     *
-     * @param springAppCfg Class of Spring application configuration that will be used for Spring context initialization.
-     */
-    private static void igniteSpringDataInit(Class<?> springAppCfg) {
-        ctx = new AnnotationConfigApplicationContext();
-
-        // Explicitly registering Spring configuration.
-        ctx.register(springAppCfg);
-
-        ctx.refresh();
-
-        // Getting a reference to PersonRepository.
-        repo = ctx.getBean(PersonRepository.class);
-    }
-
-    /**
-     * Fills the repository in with sample data.
-     */
-    private static void populateRepository() {
-        TreeMap<Long, Person> persons = new TreeMap<>();
-
-        persons.put(1L, new Person(1L, 2000L, "John", "Smith", 15000, "Worked for Apple"));
-        persons.put(2L, new Person(2L, 2000L, "Brad", "Pitt", 16000, "Worked for Oracle"));
-        persons.put(3L, new Person(3L, 1000L, "Mark", "Tomson", 10000, "Worked for Sun"));
-        persons.put(4L, new Person(4L, 2000L, "Erick", "Smith", 13000, "Worked for Apple"));
-        persons.put(5L, new Person(5L, 1000L, "John", "Rozenberg", 25000, "Worked for RedHat"));
-        persons.put(6L, new Person(6L, 2000L, "Denis", "Won", 35000, "Worked for CBS"));
-        persons.put(7L, new Person(7L, 1000L, "Abdula", "Adis", 45000, "Worked for NBC"));
-        persons.put(8L, new Person(8L, 2000L, "Roman", "Ive", 15000, "Worked for Sun"));
-
-        // Adding data into the repository.
-        repo.save(persons);
-
-        System.out.println("\n>>> Added " + repo.count() + " Persons into the repository.");
-    }
-
-    /**
-     * Gets a list of Persons using standard read operations.
-     */
-    private static void findPersons() {
-        // Getting Person with specific ID.
-        Person person = repo.findById(2L).orElse(null);
-
-        System.out.println("\n>>> Found Person [id=" + 2L + ", val=" + person + "]");
-
-        // Getting a list of Persons.
-
-        ArrayList<Long> ids = new ArrayList<>();
-
-        for (long i = 0; i < 5; i++)
-            ids.add(i);
-
-        Iterator<Person> persons = repo.findAllById(ids).iterator();
-
-        System.out.println("\n>>> Persons list for specific ids: ");
-
-        while (persons.hasNext())
-            System.out.println("   >>>   " + persons.next());
-    }
-
-    /**
-     * Execute advanced queries over the repository.
-     */
-    private static void queryRepository() {
-        System.out.println("\n>>> Persons with name 'John':");
-
-        List<Person> persons = repo.findByFirstName("John");
-
-        for (Person person: persons)
-            System.out.println("   >>>   " + person);
-
-
-        Cache.Entry<Long, Person> topPerson = repo.findTopByLastNameLike("Smith");
-
-        System.out.println("\n>>> Top Person with surname 'Smith': " + topPerson.getValue());
-
-
-        List<Long> ids = repo.selectId(1000L, new PageRequest(0, 4));
-
-        System.out.println("\n>>> Persons working for organization with ID > 1000: ");
-
-        for (Long id: ids)
-            System.out.println("   >>>   [id=" + id + "]");
-    }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java
deleted file mode 100644
index e7e6348..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Address.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinaryReader;
-import org.apache.ignite.binary.BinaryWriter;
-import org.apache.ignite.binary.Binarylizable;
-
-/**
- * Employee address.
- * <p>
- * This class implements {@link Binarylizable} only for example purposes,
- * in order to show how to customize serialization and deserialization of
- * binary objects.
- */
-public class Address implements Binarylizable {
-    /** Street. */
-    private String street;
-
-    /** ZIP code. */
-    private int zip;
-
-    /**
-     * Required for binary deserialization.
-     */
-    public Address() {
-        // No-op.
-    }
-
-    /**
-     * @param street Street.
-     * @param zip ZIP code.
-     */
-    public Address(String street, int zip) {
-        this.street = street;
-        this.zip = zip;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
-        writer.writeString("street", street);
-        writer.writeInt("zip", zip);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
-        street = reader.readString("street");
-        zip = reader.readInt("zip");
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Address [street=" + street +
-            ", zip=" + zip + ']';
-    }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java
deleted file mode 100644
index 7996793..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Employee.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-import java.util.Collection;
-
-/**
- * This class represents employee object.
- */
-public class Employee {
-    /** Name. */
-    private String name;
-
-    /** Salary. */
-    private long salary;
-
-    /** Address. */
-    private Address addr;
-
-    /** Departments. */
-    private Collection<String> departments;
-
-    /**
-     * Required for binary deserialization.
-     */
-    public Employee() {
-        // No-op.
-    }
-
-    /**
-     * @param name Name.
-     * @param salary Salary.
-     * @param addr Address.
-     * @param departments Departments.
-     */
-    public Employee(String name, long salary,Address addr, Collection<String> departments) {
-        this.name = name;
-        this.salary = salary;
-        this.addr = addr;
-        this.departments = departments;
-    }
-
-    /**
-     * @return Name.
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * @return Salary.
-     */
-    public long salary() {
-        return salary;
-    }
-
-    /**
-     * @return Address.
-     */
-    public Address address() {
-        return addr;
-    }
-
-    /**
-     * @return Departments.
-     */
-    public Collection<String> departments() {
-        return departments;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Employee [name=" + name +
-            ", salary=" + salary +
-            ", address=" + addr +
-            ", departments=" + departments + ']';
-    }
-}
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java b/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java
deleted file mode 100644
index 7bcb0c2..0000000
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/OrganizationType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.examples.model;
-
-/**
- * Organization type enum.
- */
-public enum OrganizationType {
-    /** Non-profit organization. */
-    NON_PROFIT,
-
-    /** Private organization. */
-    PRIVATE,
-
-    /** Government organization. */
-    GOVERNMENT
-}
diff --git a/modules/spring-data-2.0-ext/licenses/apache-2.0.txt b/modules/spring-data-2.0-ext/licenses/apache-2.0.txt
deleted file mode 100644
index d645695..0000000
--- a/modules/spring-data-2.0-ext/licenses/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
diff --git a/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml b/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml
deleted file mode 100755
index 3061bd4..0000000
--- a/modules/spring-data-2.0-ext/modules/core/src/test/config/log4j-test.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?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.
--->
-
-<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
-    "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-<!--
-    Log4j configuration.
--->
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
-    <!--
-        Logs System.out messages to console.
-    -->
-    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
-        <!-- Log to STDOUT. -->
-        <param name="Target" value="System.out"/>
-
-        <!-- Log from DEBUG and higher. -->
-        <param name="Threshold" value="DEBUG"/>
-
-        <!-- The default pattern: Date Priority [Category] Message\n -->
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-
-        <!-- Do not log beyond INFO level. -->
-        <filter class="org.apache.log4j.varia.LevelRangeFilter">
-            <param name="levelMin" value="DEBUG"/>
-            <param name="levelMax" value="INFO"/>
-        </filter>
-    </appender>
-
-    <!--
-        Logs all System.err messages to console.
-    -->
-    <appender name="CONSOLE_ERR" class="org.apache.log4j.ConsoleAppender">
-        <!-- Log to STDERR. -->
-        <param name="Target" value="System.err"/>
-
-        <!-- Log from WARN and higher. -->
-        <param name="Threshold" value="WARN"/>
-
-        <!-- The default pattern: Date Priority [Category] Message\n -->
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-    </appender>
-
-    <!--
-        Logs all output to specified file.
-    -->
-    <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
-        <param name="Threshold" value="DEBUG"/>
-        <param name="File" value="ignite/work/log/ignite.log"/>
-        <param name="Append" value="true"/>
-        <param name="MaxFileSize" value="10MB"/>
-        <param name="MaxBackupIndex" value="10"/>
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-    </appender>
-
-    <!-- Disable all open source debugging. -->
-    <category name="org">
-        <level value="INFO"/>
-    </category>
-
-    <category name="org.eclipse.jetty">
-        <level value="INFO"/>
-    </category>
-
-    <!-- Default settings. -->
-    <root>
-        <!-- Print at info by default. -->
-        <level value="INFO"/>
-
-        <!-- Append to file and console. -->
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="CONSOLE_ERR"/>
-    </root>
-</log4j:configuration>
diff --git a/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties b/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties
deleted file mode 100644
index 0faf5b8..0000000
--- a/modules/spring-data-2.0-ext/modules/core/src/test/config/tests.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Local address to bind to.
-local.ip=127.0.0.1
-
-# TCP communication port
-comm.tcp.port=30010
diff --git a/modules/spring-data-2.0-ext/pom.xml b/modules/spring-data-2.0-ext/pom.xml
deleted file mode 100644
index d2d3f5b..0000000
--- a/modules/spring-data-2.0-ext/pom.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?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.
--->
-
-<!--
-    POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.ignite</groupId>
-        <artifactId>ignite-extensions-parent</artifactId>
-        <version>1</version>
-        <relativePath>../../parent</relativePath>
-    </parent>
-
-    <artifactId>ignite-spring-data-2.0-ext</artifactId>
-    <version>${ignite-spring-data-2.0-ext.version}</version>
-    <url>http://ignite.apache.org</url>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-indexing</artifactId>
-            <version>${ignite.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-commons</artifactId>
-            <version>${ignite-spring-data-commons.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring-5.0.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-tx</artifactId>
-            <version>${spring-5.0.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.0.version}</version>
-            <scope>provided</scope>
-            <!-- Exclude slf4j logging in favor of log4j -->
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>jcl-over-slf4j</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>${commons.lang.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-log4j</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-context</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-tools</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java
deleted file mode 100644
index 8ba8de6..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/IgniteRepository.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository;
-
-import java.io.Serializable;
-import java.util.Map;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
-    /**
-     * Returns the Ignite instance bound to the repository
-     *
-     * @return the Ignite instance bound to the repository
-     */
-    public Ignite ignite();
-
-    /**
-     * Returns the Ignite Cache bound to the repository
-     *
-     * @return the Ignite Cache bound to the repository
-     */
-    public IgniteCache<K, V> cache();
-
-    /**
-     * Saves a given entity using provided key.
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>    Entity type.
-     * @param key    Entity's key.
-     * @param entity Entity to save.
-     * @return Saved entity.
-     */
-    public <S extends V> S save(K key, S entity);
-
-    /**
-     * Saves all given keys and entities combinations.
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>      Type of entities.
-     * @param entities Map of key-entities pairs to save.
-     * @return Saved entities.
-     */
-    public <S extends V> Iterable<S> save(Map<K, S> entities);
-
-    /**
-     * Saves a given entity using provided key with expiry policy
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>       Entity type.
-     * @param key       Entity's key.
-     * @param entity    Entity to save.
-     * @param expiryPlc ExpiryPolicy to apply, if not null.
-     * @return Saved entity.
-     */
-    public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
-
-    /**
-     * Saves all given keys and entities combinations with expiry policy
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>       Type of entities.
-     * @param entities  Map of key-entities pairs to save.
-     * @param expiryPlc ExpiryPolicy to apply, if not null.
-     * @return Saved entities.
-     */
-    public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
-
-    /**
-     * Deletes all the entities for the provided ids.
-     *
-     * @param ids List of ids to delete.
-     */
-    public void deleteAllById(Iterable<K> ids);
-
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java
deleted file mode 100644
index ed422a9..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/DynamicQueryConfig.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-/**
- * Runtime Dynamic query configuration.
- * <p>
- * Can be used as special repository method parameter to provide at runtime:
- * <ol>
- * <li>Dynamic query string (requires {@link Query#dynamicQuery()} == true)
- * <li>Ignite query tuning*
- * </ol>
- * <p>
- * * Please, note that {@link Query} annotation parameters will be ignored in favor of those defined in
- * {@link DynamicQueryConfig} parameter if present.
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public class DynamicQueryConfig {
-    /** */
-    private String value = "";
-
-    /** */
-    private boolean textQuery;
-
-    /** */
-    private boolean forceFieldsQry;
-
-    /** */
-    private boolean collocated;
-
-    /** */
-    private int timeout;
-
-    /** */
-    private boolean enforceJoinOrder;
-
-    /** */
-    private boolean distributedJoins;
-
-    /** */
-    private boolean lazy;
-
-    /** */
-    private boolean local;
-
-    /** */
-    private int[] parts;
-
-    /** */
-    private int limit;
-
-    /**
-     * From Query annotation.
-     *
-     * @param queryConfiguration the query configuration
-     * @return the dynamic query config
-     */
-    public static DynamicQueryConfig fromQueryAnnotation(Query queryConfiguration) {
-        DynamicQueryConfig config = new DynamicQueryConfig();
-        if (queryConfiguration != null) {
-            config.value = queryConfiguration.value();
-            config.collocated = queryConfiguration.collocated();
-            config.timeout = queryConfiguration.timeout();
-            config.enforceJoinOrder = queryConfiguration.enforceJoinOrder();
-            config.distributedJoins = queryConfiguration.distributedJoins();
-            config.lazy = queryConfiguration.lazy();
-            config.parts = queryConfiguration.parts();
-            config.local = queryConfiguration.local();
-            config.limit = queryConfiguration.limit();
-        }
-        return config;
-    }
-
-    /**
-     * Query text string.
-     *
-     * @return the string
-     */
-    public String value() {
-        return value;
-    }
-
-    /**
-     * Whether must use TextQuery search.
-     *
-     * @return the boolean
-     */
-    public boolean textQuery() {
-        return textQuery;
-    }
-
-    /**
-     * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
-     * statements or to not return hidden fields on SELECT * statements.
-     *
-     * @return the boolean
-     */
-    public boolean forceFieldsQuery() {
-        return forceFieldsQry;
-    }
-
-    /**
-     * Sets flag defining if this query is collocated.
-     * <p>
-     * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
-     * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
-     * of your query selection are collocated together on the same node and you group by collocated key (primary or
-     * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
-     * nodes.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     *
-     * @return the boolean
-     */
-    public boolean collocated() {
-        return collocated;
-    }
-
-    /**
-     * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
-     * timeout is exceeded. Zero value disables timeout
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     *
-     * @return the int
-     */
-    public int timeout() {
-        return timeout;
-    }
-
-    /**
-     * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
-     * tables in join. By default is {@code false}.
-     * <p>
-     * It is not recommended to enable this property until you are sure that your indexes and the query itself are
-     * correct and tuned as much as possible but query optimizer still produces wrong join order.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     *
-     * @return the boolean
-     */
-    public boolean enforceJoinOrder() {
-        return enforceJoinOrder;
-    }
-
-    /**
-     * Specify if distributed joins are enabled for this query.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     *
-     * @return the boolean
-     */
-    public boolean distributedJoins() {
-        return distributedJoins;
-    }
-
-    /**
-     * Sets lazy query execution flag.
-     * <p>
-     * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
-     * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
-     * increasing concurrency.
-     * <p>
-     * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
-     * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
-     * consumption at the cost of moderate performance hit.
-     * <p>
-     * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     *
-     * @return the boolean
-     */
-    public boolean lazy() {
-        return lazy;
-    }
-
-    /**
-     * Sets whether this query should be executed on local node only.
-     *
-     * @return the boolean
-     */
-    public boolean local() {
-        return local;
-    }
-
-    /**
-     * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
-     * partitions.
-     * <p>
-     * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     *
-     * @return the int [ ]
-     */
-    public int[] parts() {
-        return parts;
-    }
-
-    /**
-     * Gets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
-     *
-     * @return Limit value.
-     */
-    public int limit() {
-        return limit;
-    }
-
-    /**
-     * Sets value.
-     *
-     * @param value the value
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setValue(String value) {
-        this.value = value;
-        return this;
-    }
-
-    /**
-     * Sets text query.
-     *
-     * @param textQuery the text query
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setTextQuery(boolean textQuery) {
-        this.textQuery = textQuery;
-        return this;
-    }
-
-    /**
-     * Sets force fields query.
-     *
-     * @param forceFieldsQuery the force fields query
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setForceFieldsQuery(boolean forceFieldsQuery) {
-        forceFieldsQry = forceFieldsQuery;
-        return this;
-    }
-
-    /**
-     * Sets collocated.
-     *
-     * @param collocated the collocated
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setCollocated(boolean collocated) {
-        this.collocated = collocated;
-        return this;
-    }
-
-    /**
-     * Sets timeout.
-     *
-     * @param timeout the timeout
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setTimeout(int timeout) {
-        this.timeout = timeout;
-        return this;
-    }
-
-    /**
-     * Sets enforce join order.
-     *
-     * @param enforceJoinOrder the enforce join order
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setEnforceJoinOrder(boolean enforceJoinOrder) {
-        this.enforceJoinOrder = enforceJoinOrder;
-        return this;
-    }
-
-    /**
-     * Sets distributed joins.
-     *
-     * @param distributedJoins the distributed joins
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setDistributedJoins(boolean distributedJoins) {
-        this.distributedJoins = distributedJoins;
-        return this;
-    }
-
-    /**
-     * Sets lazy.
-     *
-     * @param lazy the lazy
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setLazy(boolean lazy) {
-        this.lazy = lazy;
-        return this;
-    }
-
-    /**
-     * Sets local.
-     *
-     * @param local the local
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setLocal(boolean local) {
-        this.local = local;
-        return this;
-    }
-
-    /**
-     * Sets parts.
-     *
-     * @param parts the parts
-     * @return this for chaining
-     */
-    public DynamicQueryConfig setParts(int[] parts) {
-        this.parts = parts;
-        return this;
-    }
-
-    /**
-     * Sets limit to response records count for TextQuery.
-     *
-     * @param limit If 0 or less, considered to be no limit.
-     * @return {@code this} For chaining.
-     */
-    public DynamicQueryConfig setLimit(int limit) {
-        this.limit = limit;
-        return this;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java
deleted file mode 100644
index 1bab4ca..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/EnableIgniteRepositories.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryImpl;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Import;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-
-/**
- * Annotation to activate Apache Ignite repositories. If no base package is configured through either {@link #value()},
- * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-@Import(IgniteRepositoriesRegistar.class)
-public @interface EnableIgniteRepositories {
-    /**
-     * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
-     * {@code @EnableIgniteRepositories("org.my.pkg")} instead of
-     * {@code @EnableIgniteRepositories(basePackages="org.my.pkg")}.
-     */
-    String[] value() default {};
-
-    /**
-     * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with)
-     * this attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
-     */
-    String[] basePackages() default {};
-
-    /**
-     * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components.
-     * The package of each class specified will be scanned. Consider creating a special no-op marker class or interface
-     * in each package that serves no purpose other than being referenced by this attribute.
-     */
-    Class<?>[] basePackageClasses() default {};
-
-    /**
-     * Specifies which types are not eligible for component scanning.
-     */
-    Filter[] excludeFilters() default {};
-
-    /**
-     * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
-     * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or
-     * filters.
-     */
-    Filter[] includeFilters() default {};
-
-    /**
-     * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
-     * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
-     * for {@code PersonRepositoryImpl}.
-     *
-     * @return Postfix to be used when looking up custom repository implementations.
-     */
-    String repositoryImplementationPostfix() default "Impl";
-
-    /**
-     * Configures the location of where to find the Spring Data named queries properties file.
-     *
-     * @return Location of where to find the Spring Data named queries properties file.
-     */
-    String namedQueriesLocation() default "";
-
-    /**
-     * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
-     * {@link Key#CREATE_IF_NOT_FOUND}.
-     *
-     * @return Key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods.
-     */
-    Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
-
-    /**
-     * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
-     * IgniteRepositoryFactoryBean}.
-     *
-     * @return {@link FactoryBean} class to be used for each repository instance.
-     */
-    Class<?> repositoryFactoryBeanClass() default IgniteRepositoryFactoryBean.class;
-
-    /**
-     * Configure the repository base class to be used to create repository proxies for this particular configuration.
-     *
-     * @return Repository base class to be used to create repository proxies for this particular configuration.
-     */
-    Class<?> repositoryBaseClass() default IgniteRepositoryImpl.class;
-
-    /**
-     * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
-     * repositories infrastructure.
-     */
-    boolean considerNestedRepositories() default false;
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java
deleted file mode 100644
index 83ff7ff..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoriesRegistar.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Annotation;
-import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryBeanDefinitionRegistrarSupport}.
- */
-public class IgniteRepositoriesRegistar extends RepositoryBeanDefinitionRegistrarSupport {
-    /** {@inheritDoc} */
-    @Override protected Class<? extends Annotation> getAnnotation() {
-        return EnableIgniteRepositories.class;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected RepositoryConfigurationExtension getExtension() {
-        return new IgniteRepositoryConfigurationExtension();
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java
deleted file mode 100644
index de8cf0b..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/IgniteRepositoryConfigurationExtension.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.util.Collection;
-import java.util.Collections;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.support.IgniteProxyFactory;
-import org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationSource;
-
-import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
- */
-public class IgniteRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
-    /** Name of the auto-registered Ignite proxy factory bean. */
-    private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
-
-    /** Name of the auto-registered Ignite proxy bean prototype. */
-    private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
-
-    /** {@inheritDoc} */
-    @Override public String getModuleName() {
-        return "Apache Ignite";
-    }
-
-    /** {@inheritDoc} */
-    @Override protected String getModulePrefix() {
-        return "ignite";
-    }
-
-    /** {@inheritDoc} */
-    @Override public String getRepositoryFactoryBeanClassName() {
-        return IgniteRepositoryFactoryBean.class.getName();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Collection<Class<?>> getIdentifyingTypes() {
-        return Collections.singleton(IgniteRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
-        registerIfNotAlreadyRegistered(
-            BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
-            registry,
-            IGNITE_PROXY_FACTORY_BEAN_NAME,
-            cfg);
-
-        registerIfNotAlreadyRegistered(
-            BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
-                .setScope(SCOPE_PROTOTYPE)
-                .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
-                .getBeanDefinition(),
-            registry,
-            IGNITE_PROXY_BEAN_NAME,
-            cfg);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java
deleted file mode 100644
index 2db7c25..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/Query.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-
-/**
- * Annotation to provide a user defined query for a method.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Query {
-    /**
-     * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
-     * (only if textQuery = false (default))
-     */
-    String value() default "";
-
-    /**
-     * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
-     * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
-     *
-     * @see RepositoryConfig#igniteInstance()
-     */
-    boolean textQuery() default false;
-
-    /**
-     * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
-     * statements or to not return hidden fields on SELECT * statements.
-     */
-    boolean forceFieldsQuery() default false;
-
-    /**
-     * Sets flag defining if this query is collocated.
-     * <p>
-     * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
-     * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
-     * of your query selection are collocated together on the same node and you group by collocated key (primary or
-     * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
-     * nodes.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean collocated() default false;
-
-    /**
-     * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
-     * timeout is exceeded. Zero value disables timeout
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    int timeout() default 0;
-
-    /**
-     * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
-     * tables in join. By default is {@code false}.
-     * <p>
-     * It is not recommended to enable this property until you are sure that your indexes and the query itself are
-     * correct and tuned as much as possible but query optimizer still produces wrong join order.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean enforceJoinOrder() default false;
-
-    /**
-     * Specify if distributed joins are enabled for this query.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    boolean distributedJoins() default false;
-
-    /**
-     * Sets lazy query execution flag.
-     * <p>
-     * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
-     * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
-     * increasing concurrency.
-     * <p>
-     * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
-     * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
-     * consumption at the cost of moderate performance hit.
-     * <p>
-     * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean lazy() default false;
-
-    /**
-     * Sets whether this query should be executed on local node only.
-     */
-    boolean local() default false;
-
-    /**
-     * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
-     * partitions.
-     * <p>
-     * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    int[] parts() default {};
-
-    /**
-     * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
-     * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
-     * <p>
-     * Please, note that  {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
-     * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
-     */
-    boolean dynamicQuery() default false;
-
-    /**
-     * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
-     */
-    int limit() default 0;
-
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java
deleted file mode 100644
index a156d81..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/RepositoryConfig.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-
-/**
- * The annotation can be used to pass Ignite specific parameters to a bound repository.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-public @interface RepositoryConfig {
-    /**
-     * Cache name string.
-     *
-     * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
-     */
-    String cacheName() default "";
-
-    /**
-     * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
-     * Ignite cluster.
-     */
-    String igniteInstance() default "igniteInstance";
-
-    /**
-     * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
-     * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
-     */
-    String igniteCfg() default "igniteCfg";
-
-    /**
-     * Ignite spring cfg path string. Default "igniteSpringCfgPath".
-     *
-     * @return A path to Ignite's Spring XML configuration spring bean name
-     */
-    String igniteSpringCfgPath() default "igniteSpringCfgPath";
-
-    /**
-     * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
-     * <p>
-     * Tells to Ignite Repository factory wether cache should be auto created if not exists.
-     *
-     * @return the boolean
-     */
-    boolean autoCreateCache() default false;
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java
deleted file mode 100644
index 1c7b2f9..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/config/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes Spring Data integration related configuration files.
- */
-package org.apache.ignite.springdata20.repository.config;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java
deleted file mode 100644
index 9df5513..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains Apache Ignite Spring Data integration.
- */
-package org.apache.ignite.springdata20.repository;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java
deleted file mode 100644
index 4714f38..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/EmptyDeclaredQuery.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.util.Collections;
-import java.util.List;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * NULL-Object pattern implementation for {@link DeclaredQuery}.
- *
- * @author Jens Schauder
- */
-class EmptyDeclaredQuery implements DeclaredQuery {
-    /**
-     * An implementation implementing the NULL-Object pattern for situations where there is no query.
-     */
-    static final DeclaredQuery EMPTY_QUERY = new EmptyDeclaredQuery();
-
-    /** {@inheritDoc} */
-    @Override public boolean hasNamedParameter() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String getQueryString() {
-        return "";
-    }
-
-    /** {@inheritDoc} */
-    @Override public String getAlias() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean hasConstructorExpression() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isDefaultProjection() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public List<StringQuery.ParameterBinding> getParameterBindings() {
-        return Collections.emptyList();
-    }
-
-    /** {@inheritDoc} */
-    @Override public DeclaredQuery deriveCountQuery(@Nullable String cntQry, @Nullable String cntQryProjection) {
-        Assert.hasText(cntQry, "CountQuery must not be empty!");
-        return DeclaredQuery.of(cntQry);
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean usesJdbcStyleParameters() {
-        return false;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java
deleted file mode 100644
index b1115ae..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/ExpressionBasedStringQuery.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.util.regex.Pattern;
-import org.springframework.data.repository.core.EntityMetadata;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.expression.Expression;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-import org.springframework.util.Assert;
-
-/**
- * Extension of {@link StringQuery} that evaluates the given query string as a SpEL template-expression.
- * <p>
- * Currently the following template variables are available:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the given entity</li>
- * <ol>
- *
- * @author Thomas Darimont
- * @author Oliver Gierke
- * @author Tom Hombergs
- */
-class ExpressionBasedStringQuery extends StringQuery {
-    /**
-     * Expression parameter.
-     */
-    private static final String EXPRESSION_PARAMETER = "?#{";
-
-    /**
-     * Quoted expression parameter.
-     */
-    private static final String QUOTED_EXPRESSION_PARAMETER = "?__HASH__{";
-
-    /**
-     * Expression parameter quoting.
-     */
-    private static final Pattern EXPRESSION_PARAMETER_QUOTING = Pattern.compile(Pattern.quote(EXPRESSION_PARAMETER));
-
-    /**
-     * Expression parameter unquoting.
-     */
-    private static final Pattern EXPRESSION_PARAMETER_UNQUOTING = Pattern.compile(
-        Pattern.quote(QUOTED_EXPRESSION_PARAMETER));
-
-    /**
-     * Entity name.
-     */
-    private static final String ENTITY_NAME = "entityName";
-
-    /**
-     * Entity name variable.
-     */
-    private static final String ENTITY_NAME_VARIABLE = "#" + ENTITY_NAME;
-
-    /**
-     * Entity name variable expression.
-     */
-    private static final String ENTITY_NAME_VARIABLE_EXPRESSION = "#{" + ENTITY_NAME_VARIABLE + "}";
-
-    /**
-     * Creates a new instance for the given query and {@link EntityMetadata}.
-     *
-     * @param qry      must not be {@literal null} or empty.
-     * @param metadata must not be {@literal null}.
-     * @param parser   must not be {@literal null}.
-     */
-    public ExpressionBasedStringQuery(String qry, RepositoryMetadata metadata, SpelExpressionParser parser) {
-        super(renderQueryIfExpressionOrReturnQuery(qry, metadata, parser));
-    }
-
-    /**
-     * Creates an instance from a given {@link DeclaredQuery}.
-     *
-     * @param qry      the original query. Must not be {@literal null}.
-     * @param metadata the {@link RepositoryMetadata} for the given entity. Must not be {@literal null}.
-     * @param parser   Parser for resolving SpEL expressions. Must not be {@literal null}.
-     * @return A query supporting SpEL expressions.
-     */
-    static ExpressionBasedStringQuery from(DeclaredQuery qry,
-        RepositoryMetadata metadata,
-        SpelExpressionParser parser) {
-        return new ExpressionBasedStringQuery(qry.getQueryString(), metadata, parser);
-    }
-
-    /**
-     * @param qry,     the query expression potentially containing a SpEL expression. Must not be {@literal null}.}
-     * @param metadata the {@link RepositoryMetadata} for the given entity. Must not be {@literal null}.
-     * @param parser   Must not be {@literal null}.
-     * @return rendered query
-     */
-    private static String renderQueryIfExpressionOrReturnQuery(String qry,
-        RepositoryMetadata metadata,
-        SpelExpressionParser parser) {
-
-        Assert.notNull(qry, "query must not be null!");
-        Assert.notNull(metadata, "metadata must not be null!");
-        Assert.notNull(parser, "parser must not be null!");
-
-        if (!containsExpression(qry))
-            return qry;
-
-        StandardEvaluationContext evalCtx = new StandardEvaluationContext();
-        evalCtx.setVariable(ENTITY_NAME, metadata.getDomainType().getSimpleName());
-
-        qry = potentiallyQuoteExpressionsParameter(qry);
-
-        Expression expr = parser.parseExpression(qry, ParserContext.TEMPLATE_EXPRESSION);
-
-        String result = expr.getValue(evalCtx, String.class);
-
-        if (result == null)
-            return qry;
-
-        return potentiallyUnquoteParameterExpressions(result);
-    }
-
-    /**
-     * @param result Result.
-     */
-    private static String potentiallyUnquoteParameterExpressions(String result) {
-        return EXPRESSION_PARAMETER_UNQUOTING.matcher(result).replaceAll(EXPRESSION_PARAMETER);
-    }
-
-    /**
-     * @param qry Query.
-     */
-    private static String potentiallyQuoteExpressionsParameter(String qry) {
-        return EXPRESSION_PARAMETER_QUOTING.matcher(qry).replaceAll(QUOTED_EXPRESSION_PARAMETER);
-    }
-
-    /**
-     * @param qry Query.
-     */
-    private static boolean containsExpression(String qry) {
-        return qry.contains(ENTITY_NAME_VARIABLE_EXPRESSION);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java
deleted file mode 100644
index f8e6d48..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQuery.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import org.apache.ignite.internal.util.typedef.internal.S;
-
-/**
- * Ignite query helper class. For internal use only.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteQuery {
-    /** */
-    enum Option {
-        /** Query will be used with Sort object. */
-        SORTING,
-
-        /** Query will be used with Pageable object. */
-        PAGINATION,
-
-        /** No advanced option. */
-        NONE
-    }
-
-    /**
-     * Query text string.
-     */
-    private final String qrySql;
-
-    /**
-     * Whether this is a SQL fields query
-     */
-    private final boolean isFieldQuery;
-
-    /**
-     * Whether this is Text query
-     */
-    private final boolean isTextQuery;
-
-    /**
-     * Whether was autogenerated (by method name)
-     */
-    private final boolean isAutogenerated;
-
-    /**
-     * Type of option.
-     */
-    private final Option option;
-
-    /**
-     * @param qrySql          the query string.
-     * @param isFieldQuery    Is field query.
-     * @param isTextQuery     Is a TextQuery
-     * @param isAutogenerated query was autogenerated
-     * @param option          Option.
-     */
-    public IgniteQuery(String qrySql,
-        boolean isFieldQuery,
-        boolean isTextQuery,
-        boolean isAutogenerated,
-        Option option) {
-        this.qrySql = qrySql;
-        this.isFieldQuery = isFieldQuery;
-        this.isTextQuery = isTextQuery;
-        this.isAutogenerated = isAutogenerated;
-        this.option = option;
-    }
-
-    /**
-     * Text string of the query.
-     *
-     * @return SQL query text string.
-     */
-    public String qryStr() {
-        return qrySql;
-    }
-
-    /**
-     * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
-     *
-     * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
-     */
-    public boolean isFieldQuery() {
-        return isFieldQuery;
-    }
-
-    /**
-     * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
-     *
-     * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
-     */
-    public boolean isTextQuery() {
-        return isTextQuery;
-    }
-
-    /**
-     * Returns {@code true} if it's autogenerated, {@code false} otherwise.
-     *
-     * @return {@code true} if it's autogenerated, {@code false} otherwise.
-     */
-    public boolean isAutogenerated() {
-        return isAutogenerated;
-    }
-
-    /**
-     * Advanced querying option.
-     *
-     * @return querying option.
-     */
-    public Option options() {
-        return option;
-    }
-
-    /** */
-    @Override public String toString() {
-        return S.toString(IgniteQuery.class, this);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java
deleted file mode 100644
index 864903a..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteQueryGenerator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Method;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.mapping.PropertyPath;
-import org.springframework.data.mapping.PropertyReferenceException;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.parser.Part;
-import org.springframework.data.repository.query.parser.PartTree;
-
-/**
- * Ignite query generator for Spring Data framework.
- */
-public class IgniteQueryGenerator {
-    /** */
-    private IgniteQueryGenerator() {
-        // No-op.
-    }
-
-    /**
-     * @param mtd      Method.
-     * @param metadata Metadata.
-     * @return Generated ignite query.
-     */
-    public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
-        PartTree parts;
-
-        try {
-            parts = new PartTree(mtd.getName(), metadata.getDomainType());
-        }
-        catch (PropertyReferenceException e) {
-            parts = new PartTree(mtd.getName(), metadata.getIdType());
-        }
-
-        boolean isCountOrFieldQuery = parts.isCountProjection();
-
-        StringBuilder sql = new StringBuilder();
-
-        if (parts.isDelete()) {
-            sql.append("DELETE ");
-
-            // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
-            isCountOrFieldQuery = true;
-        }
-        else {
-            sql.append("SELECT ");
-
-            if (parts.isDistinct())
-                throw new UnsupportedOperationException("DISTINCT clause in not supported.");
-
-            if (isCountOrFieldQuery)
-                sql.append("COUNT(1) ");
-            else
-                sql.append("* ");
-        }
-
-        sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
-
-        if (parts.iterator().hasNext()) {
-            sql.append(" WHERE ");
-
-            for (PartTree.OrPart orPart : parts) {
-                sql.append("(");
-
-                for (Part part : orPart) {
-                    handleQueryPart(sql, part, metadata.getDomainType());
-                    sql.append(" AND ");
-                }
-
-                sql.delete(sql.length() - 5, sql.length());
-
-                sql.append(") OR ");
-            }
-
-            sql.delete(sql.length() - 4, sql.length());
-        }
-
-        addSorting(sql, parts.getSort());
-
-        if (parts.isLimiting()) {
-            sql.append(" LIMIT ");
-            sql.append(parts.getMaxResults().intValue());
-        }
-
-        return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
-    }
-
-    /**
-     * Add a dynamic part of query for the sorting support.
-     *
-     * @param sql  SQL text string.
-     * @param sort Sort method.
-     * @return Sorting criteria in StringBuilder.
-     */
-    public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
-        if (sort != null && sort != Sort.unsorted()) {
-            sql.append(" ORDER BY ");
-
-            for (Sort.Order order : sort) {
-                sql.append(order.getProperty()).append(" ").append(order.getDirection());
-
-                if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
-                    sql.append(" ").append("NULL ");
-
-                    switch (order.getNullHandling()) {
-                        case NULLS_FIRST:
-                            sql.append("FIRST");
-                            break;
-                        case NULLS_LAST:
-                            sql.append("LAST");
-                            break;
-                        default:
-                    }
-                }
-                sql.append(", ");
-            }
-
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        return sql;
-    }
-
-    /**
-     * Add a dynamic part of a query for the pagination support.
-     *
-     * @param sql      Builder instance.
-     * @param pageable Pageable instance.
-     * @return Builder instance.
-     */
-    public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
-
-        addSorting(sql, pageable.getSort());
-
-        sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
-
-        return sql;
-    }
-
-    /**
-     * Determines whether query is dynamic or not (by list of method parameters)
-     *
-     * @param mtd Method.
-     * @return type of options
-     */
-    public static IgniteQuery.Option getOptions(Method mtd) {
-        IgniteQuery.Option option = IgniteQuery.Option.NONE;
-
-        Class<?>[] types = mtd.getParameterTypes();
-        if (types.length > 0) {
-            Class<?> type = types[types.length - 1];
-
-            if (Sort.class.isAssignableFrom(type))
-                option = IgniteQuery.Option.SORTING;
-            else if (Pageable.class.isAssignableFrom(type))
-                option = IgniteQuery.Option.PAGINATION;
-        }
-
-        for (int i = 0; i < types.length - 1; i++) {
-            Class<?> tp = types[i];
-
-            if (tp == Sort.class || tp == Pageable.class)
-                throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
-        }
-
-        return option;
-    }
-
-    /**
-     * Check and correct table name if using column name from compound key.
-     */
-    private static String getColumnName(Part part, Class<?> domainType) {
-        PropertyPath prperty = part.getProperty();
-
-        if (prperty.getType() != domainType)
-            return domainType.getSimpleName() + "." + prperty.getSegment();
-        else
-            return part.toString();
-    }
-
-    /**
-     * Transform part to qryStr expression
-     */
-    private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
-        sql.append("(");
-
-        sql.append(getColumnName(part, domainType));
-
-        switch (part.getType()) {
-            case SIMPLE_PROPERTY:
-                sql.append("=?");
-                break;
-            case NEGATING_SIMPLE_PROPERTY:
-                sql.append("<>?");
-                break;
-            case GREATER_THAN:
-                sql.append(">?");
-                break;
-            case GREATER_THAN_EQUAL:
-                sql.append(">=?");
-                break;
-            case LESS_THAN:
-                sql.append("<?");
-                break;
-            case LESS_THAN_EQUAL:
-                sql.append("<=?");
-                break;
-            case IS_NOT_NULL:
-                sql.append(" IS NOT NULL");
-                break;
-            case IS_NULL:
-                sql.append(" IS NULL");
-                break;
-            case BETWEEN:
-                sql.append(" BETWEEN ? AND ?");
-                break;
-            case FALSE:
-                sql.append(" = FALSE");
-                break;
-            case TRUE:
-                sql.append(" = TRUE");
-                break;
-            //TODO: review this legacy code, LIKE should be -> LIKE ?
-            case LIKE:
-            case CONTAINING:
-                sql.append(" LIKE '%' || ? || '%'");
-                break;
-            case NOT_CONTAINING:
-                //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
-            case NOT_LIKE:
-                sql.append(" NOT LIKE '%' || ? || '%'");
-                break;
-            case STARTING_WITH:
-                sql.append(" LIKE  ? || '%'");
-                break;
-            case ENDING_WITH:
-                sql.append(" LIKE '%' || ?");
-                break;
-            case IN:
-                sql.append(" IN ?");
-                break;
-            case NOT_IN:
-                sql.append(" NOT IN ?");
-                break;
-            case REGEX:
-                sql.append(" REGEXP ?");
-                break;
-            case NEAR:
-            case AFTER:
-            case BEFORE:
-            case EXISTS:
-            default:
-                throw new UnsupportedOperationException(part.getType() + " is not supported!");
-        }
-
-        sql.append(")");
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
deleted file mode 100644
index 2724940..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/IgniteRepositoryQuery.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.cache.Cache;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.reflect.FieldUtils;
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.cache.query.FieldsQueryCursor;
-import org.apache.ignite.cache.query.Query;
-import org.apache.ignite.cache.query.QueryCursor;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.cache.query.SqlQuery;
-import org.apache.ignite.cache.query.TextQuery;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.springdata20.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata20.repository.query.StringQuery.ParameterBinding;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.SliceImpl;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.projection.ProjectionFactory;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameter;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.StringUtils;
-
-import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
-import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
-import static org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactory.isFieldQuery;
-
-/**
- * Ignite query implementation.
- * <p>
- * <p>
- * Features:
- * <ol>
- * <li> Supports query tuning parameters</li>
- * <li> Supports projections</li>
- * <li> Supports Page and Stream responses</li>
- * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
- * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
- * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
- * <ol>
- * <li><b>Template variables</b>:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the domain entity</li>
- * </ol>
- * </li>
- * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
- * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
- * ?#{[0]} or ?#{#myParamName}</li>
- * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
- * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
- * through SpEL EvaluationContext extension model.</li>
- * </ol>
- * Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
- * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
- * Pageable pageable);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
- * User searchUserByEmail(String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
- * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
- * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
- * <pre>
- * {@code @Query}(textQuery = true, value = "email: #{#email}")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
- * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{[0]}")
- * List<User> searchUsersByText(String textToSearch, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
- * .match('city', #city)).build()}")
- * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
- *
- * {@code @Query}(dynamicQuery = true)
- * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
- * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
- *
- * ...
- * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
- * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
- *
- * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
- * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
- *
- * </pre>
- * </li>
- * </ol>
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@SuppressWarnings("unchecked")
-public class IgniteRepositoryQuery implements RepositoryQuery {
-    /**
-     * Defines the way how to process query result
-     */
-    private enum ReturnStrategy {
-        /** Need to return only one value. */
-        ONE_VALUE,
-
-        /** Need to return one cache entry */
-        CACHE_ENTRY,
-
-        /** Need to return list of cache entries */
-        LIST_OF_CACHE_ENTRIES,
-
-        /** Need to return list of values */
-        LIST_OF_VALUES,
-
-        /** Need to return list of lists */
-        LIST_OF_LISTS,
-
-        /** Need to return slice */
-        SLICE_OF_VALUES,
-
-        /** Slice of cache entries */
-        SLICE_OF_CACHE_ENTRIES,
-
-        /** Slice of lists */
-        SLICE_OF_LISTS,
-
-        /** Need to return Page of values */
-        PAGE_OF_VALUES,
-
-        /** Need to return stream of values */
-        STREAM_OF_VALUES,
-    }
-
-    /** */
-    private final Class<?> type;
-
-    /** Domain entitiy field descriptors mapped to their names in lower case. */
-    private final Map<String, Field> domainEntitiyFields;
-
-    /** */
-    private final IgniteQuery staticQuery;
-
-    /** */
-    private final IgniteCacheProxy<?, ?> cache;
-
-    /** */
-    private final Method mtd;
-
-    /** */
-    private final RepositoryMetadata metadata;
-
-    /** */
-    private final ProjectionFactory factory;
-
-    /** */
-    private final ReturnStrategy staticReturnStgy;
-
-    /** Detect if returned data from method is projected */
-    private final boolean hasProjection;
-
-    /** Whether projection is dynamic (provided as method parameter) */
-    private final boolean hasDynamicProjection;
-
-    /** Dynamic projection parameter index */
-    private final int dynamicProjectionIndex;
-
-    /** Dynamic query configuration */
-    private final int dynamicQueryConfigurationIndex;
-
-    /** The return query method */
-    private final QueryMethod qMethod;
-
-    /** The return domain class of QueryMethod */
-    private final Class<?> returnedDomainClass;
-
-    /** */
-    private final SpelExpressionParser expressionParser;
-
-    /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
-    private final EvaluationContextProvider queryMethodEvaluationContextProvider;
-
-    /** Static query configuration. */
-    private final DynamicQueryConfig staticQueryConfiguration;
-
-    /**
-     * Instantiates a new Ignite repository query.
-     *
-     * @param metadata                             Metadata.
-     * @param staticQuery                          Query.
-     * @param mtd                                  Method.
-     * @param factory                              Factory.
-     * @param cache                                Cache.
-     * @param staticQueryConfiguration             the query configuration
-     * @param queryMethodEvaluationContextProvider the query method evaluation context provider
-     */
-    public IgniteRepositoryQuery(
-        RepositoryMetadata metadata,
-        @Nullable IgniteQuery staticQuery,
-        Method mtd,
-        ProjectionFactory factory,
-        IgniteCacheProxy<? ,?> cache,
-        @Nullable DynamicQueryConfig staticQueryConfiguration,
-        EvaluationContextProvider queryMethodEvaluationContextProvider) {
-        this.metadata = metadata;
-        this.mtd = mtd;
-        this.factory = factory;
-        type = metadata.getDomainType();
-
-        domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
-            .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
-
-        this.cache = cache;
-
-        this.staticQueryConfiguration = staticQueryConfiguration;
-        this.staticQuery = staticQuery;
-
-        if (this.staticQuery != null)
-            staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
-        else
-            staticReturnStgy = null;
-
-        expressionParser = new SpelExpressionParser();
-        this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
-
-        qMethod = getQueryMethod();
-
-        // control projection
-        hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
-        hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
-            .isProjecting();
-
-        dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
-
-        returnedDomainClass = getQueryMethod().getReturnedObjectType();
-
-        dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
-
-        // ensure dynamic query configuration param exists if dynamicQuery = true
-        if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
-            throw new IllegalStateException(
-                "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
-                    + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
-        }
-    }
-
-    /**
-     * {@inheritDoc} @param values the values
-     *
-     * @return the object
-     */
-    @Override public Object execute(Object[] values) {
-        Object[] parameters = values;
-
-        // config via Query annotation (dynamicQuery = false)
-        DynamicQueryConfig config = staticQueryConfiguration;
-
-        // or condition to allow query tunning
-        if (config == null || dynamicQueryConfigurationIndex != -1) {
-            DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
-            parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
-            if (newConfig != null) {
-                // upset query configuration
-                config = newConfig;
-            }
-        }
-        // query configuration is required, via Query annotation or per parameter (within provided values param)
-        if (config == null) {
-            throw new IllegalStateException(
-                "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
-                    + ".repository.config.Query annotation, you must provide a non null method parameter of type "
-                    + "DynamicQueryConfig");
-        }
-
-        IgniteQuery qry = getQuery(config);
-
-        ReturnStrategy returnStgy = getReturnStgy(qry);
-
-        Query iQry = prepareQuery(qry, config, returnStgy, parameters);
-
-        QueryCursor qryCursor;
-
-        try {
-            qryCursor = cache.query(iQry);
-        }
-        catch (IllegalArgumentException e) {
-            if (cache instanceof IgniteClientCacheProxy) {
-                throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
-                    " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
-                    iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
-            }
-
-            throw e;
-        }
-
-        return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
-    }
-
-    /** {@inheritDoc} */
-    @Override public QueryMethod getQueryMethod() {
-        return new QueryMethod(mtd, metadata, factory);
-    }
-
-    private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
-        Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
-        int i = 0;
-        boolean found = false;
-        int index = -1;
-        while (it.hasNext()) {
-            T parameter = it.next();
-
-            if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
-                if (found) {
-                    throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
-                        + "Only ONE DynamicQueryConfig parameter is allowed");
-                }
-
-                found = true;
-                index = i;
-            }
-
-            i++;
-        }
-        return index;
-    }
-
-    /**
-     * @param mtd Method.
-     * @param isFieldQry Is field query.
-     * @return Return strategy type.
-     */
-    private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
-        Class<?> returnType = mtd.getReturnType();
-
-        if (returnType == Slice.class) {
-            if (isFieldQry) {
-                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
-                    return ReturnStrategy.SLICE_OF_LISTS;
-            }
-            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
-                return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
-            return ReturnStrategy.SLICE_OF_VALUES;
-        }
-        else if (returnType == Page.class)
-            return ReturnStrategy.PAGE_OF_VALUES;
-        else if (returnType == Stream.class)
-            return ReturnStrategy.STREAM_OF_VALUES;
-        else if (Cache.Entry.class.isAssignableFrom(returnType))
-            return ReturnStrategy.CACHE_ENTRY;
-        else if (Iterable.class.isAssignableFrom(returnType)) {
-            if (isFieldQry) {
-                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
-                    return ReturnStrategy.LIST_OF_LISTS;
-            }
-            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
-                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
-            return ReturnStrategy.LIST_OF_VALUES;
-        }
-        else
-            return ReturnStrategy.ONE_VALUE;
-    }
-
-    /**
-     * @param cls Class.
-     * @param mtd Method.
-     * @return if {@code mtd} return type is assignable from {@code cls}
-     */
-    private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
-        Type genericReturnType = mtd.getGenericReturnType();
-
-        if (!(genericReturnType instanceof ParameterizedType))
-            return false;
-
-        Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
-
-        if (actualTypeArguments.length == 0)
-            return false;
-
-        if (actualTypeArguments[0] instanceof ParameterizedType) {
-            ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
-
-            Class<?> type1 = (Class)type.getRawType();
-
-            return type1.isAssignableFrom(cls);
-        }
-
-        if (actualTypeArguments[0] instanceof Class) {
-            Class typeArg = (Class)actualTypeArguments[0];
-
-            return typeArg.isAssignableFrom(cls);
-        }
-
-        return false;
-    }
-
-    /**
-     * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
-     *
-     * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
-     * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
-     */
-    private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
-        if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
-            return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
-
-        return (T)object;
-    }
-
-    /**
-     * @param cfg Config.
-     */
-    private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
-        if (staticQuery != null)
-            return staticQuery;
-
-        if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
-            return new IgniteQuery(cfg.value(),
-                !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
-                false, IgniteQueryGenerator.getOptions(mtd));
-        }
-
-        throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
-            + ".apache.ignite.springdata.repository.config.Query annotation, you must"
-            + " provide a non null method parameter of type DynamicQueryConfig with a "
-            + "non empty value (query string) or textQuery = true");
-    }
-
-    /**
-     * @param qry Query.
-     */
-    private ReturnStrategy getReturnStgy(IgniteQuery qry) {
-        if (staticReturnStgy != null)
-            return staticReturnStgy;
-
-        if (qry != null)
-            return calcReturnType(mtd, qry.isFieldQuery());
-
-        throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
-            + "via org.apache.ignite.springdata.repository.config.Query annotation, "
-            + "you must provide a non null method parameter of type "
-            + "DynamicQueryConfig with a non empty value (query string) or textQuery "
-            + "= true");
-    }
-
-    /**
-     * @param cls Class.
-     */
-    private static boolean isPrimitiveOrWrapper(Class<?> cls) {
-        return cls.isPrimitive() ||
-            Boolean.class.equals(cls) ||
-            Byte.class.equals(cls) ||
-            Character.class.equals(cls) ||
-            Short.class.equals(cls) ||
-            Integer.class.equals(cls) ||
-            Long.class.equals(cls) ||
-            Float.class.equals(cls) ||
-            Double.class.equals(cls) ||
-            Void.class.equals(cls) ||
-            String.class.equals(cls) ||
-            UUID.class.equals(cls);
-    }
-
-    /**
-     * @param prmtrs    Prmtrs.
-     * @param qryCursor Query cursor.
-     * @return Query cursor or slice
-     */
-    @Nullable
-    private Object transformQueryCursor(IgniteQuery qry,
-        ReturnStrategy returnStgy,
-        Object[] prmtrs,
-        QueryCursor qryCursor) {
-        final Class<?> returnClass;
-
-        if (hasProjection) {
-            if (hasDynamicProjection)
-                returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
-            else
-                returnClass = returnedDomainClass;
-        }
-        else
-            returnClass = returnedDomainClass;
-
-        if (qry.isFieldQuery()) {
-            // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
-            boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
-
-            FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
-
-            Function<List<?>, ?> cWrapperTransformFunction = null;
-
-            if (type.equals(returnClass))
-                cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
-            else {
-                if (hasProjection || singlePrimitiveResult) {
-                    if (singlePrimitiveResult)
-                        cWrapperTransformFunction = row -> row.get(0);
-                    else {
-                        // Map row -> projection class
-                        cWrapperTransformFunction = row -> factory
-                            .createProjection(returnClass, rowToMap(row, fieldQryCur));
-                    }
-                }
-                else
-                    cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
-            }
-
-            QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
-                cWrapperTransformFunction);
-
-            switch (returnStgy) {
-                case PAGE_OF_VALUES:
-                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
-                case LIST_OF_VALUES:
-                    return cWrapper.getAll();
-                case STREAM_OF_VALUES:
-                    return cWrapper.stream();
-                case ONE_VALUE:
-                    Iterator<?> iter = cWrapper.iterator();
-                    if (iter.hasNext()) {
-                        Object resp = iter.next();
-                        U.closeQuiet(cWrapper);
-                        return resp;
-                    }
-                    return null;
-                case SLICE_OF_VALUES:
-                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case SLICE_OF_LISTS:
-                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case LIST_OF_LISTS:
-                    return qryCursor.getAll();
-                default:
-                    throw new IllegalStateException();
-            }
-        }
-        else {
-            Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
-
-            if (hasProjection && !type.equals(returnClass))
-                cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
-            else
-                cWrapperTransformFunction = Cache.Entry::getValue;
-
-            QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
-                (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
-
-            switch (returnStgy) {
-                case PAGE_OF_VALUES:
-                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
-                case LIST_OF_VALUES:
-                    return cWrapper.getAll();
-                case STREAM_OF_VALUES:
-                    return cWrapper.stream();
-                case ONE_VALUE:
-                    Iterator<?> iter1 = cWrapper.iterator();
-                    if (iter1.hasNext()) {
-                        Object resp = iter1.next();
-                        U.closeQuiet(cWrapper);
-                        return resp;
-                    }
-                    return null;
-                case CACHE_ENTRY:
-                    Iterator<?> iter2 = qryCursor.iterator();
-                    if (iter2.hasNext()) {
-                        Object resp2 = iter2.next();
-                        U.closeQuiet(qryCursor);
-                        return resp2;
-                    }
-                    return null;
-                case SLICE_OF_VALUES:
-                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case SLICE_OF_CACHE_ENTRIES:
-                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case LIST_OF_CACHE_ENTRIES:
-                    return qryCursor.getAll();
-                default:
-                    throw new IllegalStateException();
-            }
-        }
-    }
-
-    /**
-     * Extract bindable values
-     *
-     * @param values            values invoking query method
-     * @param queryMethodParams query method parameter definitions
-     * @param queryBindings     All parameters found on query string that need to be binded
-     * @return new list of parameters
-     */
-    private Object[] extractBindableValues(Object[] values,
-        Parameters<?, ?> queryMethodParams,
-        List<ParameterBinding> queryBindings) {
-        // no binding params then exit
-        if (queryBindings.isEmpty())
-            return values;
-
-        Object[] newValues = new Object[queryBindings.size()];
-
-        // map bindable parameters from query method: (index/name) - index
-        HashMap<String, Integer> methodParams = new HashMap<>();
-
-        // create an evaluation context for custom query
-        EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
-            .getEvaluationContext(queryMethodParams, values);
-
-        // By default queryEvalContext:
-        // - make accesible query method parameters by index:
-        // @Query("select u from User u where u.age = ?#{[0]}")
-        // List<User> findUsersByAge(int age);
-        // - make accesible query method parameters by name:
-        // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
-        // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
-
-        // query method param's index by name and position
-        queryMethodParams.getBindableParameters().forEach(p -> {
-            if (p.isNamedParameter()) {
-                // map by name (annotated by @Param)
-                methodParams.put(p.getName().get(), p.getIndex());
-            }
-            // map by position
-            methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
-        });
-
-        // process all parameters on query and extract new values to bind
-        for (int i = 0; i < queryBindings.size(); i++) {
-            ParameterBinding p = queryBindings.get(i);
-
-            if (p.isExpression()) {
-                // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
-                newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
-            }
-            else {
-                // Extract parameter value by name or position respectively from invoking values
-                newValues[i] = values[methodParams.get(
-                    p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
-            }
-        }
-
-        return newValues;
-    }
-
-    /**
-     * @param qry        Query.
-     * @param config     Config.
-     * @param returnStgy Return stgy.
-     * @param values     Values.
-     * @return prepared query for execution
-     */
-    private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
-        Object[] parameters = values;
-
-        String queryString = qry.qryStr();
-
-        Query query;
-
-        checkRequiredPageable(returnStgy, values);
-
-        if (!qry.isTextQuery()) {
-            if (!qry.isAutogenerated()) {
-                StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
-                queryString = squery.getQueryString();
-                parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
-                    squery.getParameterBindings());
-            }
-            else {
-                // remove dynamic projection from parameters
-                if (hasDynamicProjection)
-                    parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
-            }
-
-            switch (qry.options()) {
-                case SORTING:
-                    queryString = IgniteQueryGenerator
-                        .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
-                        .toString();
-                    if (qry.isAutogenerated())
-                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
-                    break;
-                case PAGINATION:
-                    queryString = IgniteQueryGenerator
-                        .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
-                        .toString();
-                    if (qry.isAutogenerated())
-                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
-                    break;
-                default:
-            }
-
-            if (qry.isFieldQuery()) {
-                SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
-                sqlFieldsQry.setArgs(parameters);
-
-                sqlFieldsQry.setCollocated(config.collocated());
-                sqlFieldsQry.setDistributedJoins(config.distributedJoins());
-                sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
-                sqlFieldsQry.setLazy(config.lazy());
-                sqlFieldsQry.setLocal(config.local());
-
-                if (config.parts() != null && config.parts().length > 0)
-                    sqlFieldsQry.setPartitions(config.parts());
-
-                sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
-                query = sqlFieldsQry;
-            }
-            else {
-                SqlQuery sqlQry = new SqlQuery(type, queryString);
-                sqlQry.setArgs(parameters);
-
-                sqlQry.setDistributedJoins(config.distributedJoins());
-                sqlQry.setLocal(config.local());
-
-                if (config.parts() != null && config.parts().length > 0)
-                    sqlQry.setPartitions(config.parts());
-
-                sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
-                query = sqlQry;
-            }
-        }
-        else {
-            int pageSize = -1;
-
-            switch (qry.options()) {
-                case PAGINATION:
-                    pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
-                    break;
-            }
-
-            // check if queryString contains SpEL template expressions and evaluate them if any
-            if (queryString.contains("#{")) {
-                EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
-                    .getEvaluationContext(getQueryMethod().getParameters(),
-                        values);
-
-                Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
-                    .getValue(queryEvalContext);
-
-                if (!(eval instanceof String)) {
-                    throw new IllegalStateException(
-                        "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
-                            .getName()
-                            + ". Please, check your expression: " + queryString);
-                }
-                queryString = (String)eval;
-            }
-
-            TextQuery textQuery = new TextQuery(type, queryString, config.limit());
-
-            textQuery.setLocal(config.local());
-
-            if (pageSize > -1)
-                textQuery.setPageSize(pageSize);
-
-            query = textQuery;
-        }
-        return query;
-    }
-
-    /**
-     * @param row SQL result row.
-     * @param cursor SQL query result cursor through which {@param row} was obtained.
-     * @return SQL result row values mapped to corresponding column names.
-     */
-    private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
-        // use treemap with case insensitive property name
-        final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
-        for (int i = 0; i < row.size(); i++) {
-            // don't want key or val columns
-            final String fieldName = cursor.getFieldName(i).toLowerCase();
-
-            if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
-                map.put(fieldName, row.get(i));
-        }
-
-        return map;
-    }
-
-    /**
-     * convert row ( with list of field values) into domain entity
-     *
-     * @param row SQL query result row.
-     * @param cursor SQL query result cursor through which {@param row} was obtained.
-     * @return Entitiy instance.
-     */
-    private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
-        Constructor<?> ctor;
-
-        try {
-            ctor = type.getDeclaredConstructor();
-
-            ctor.setAccessible(true);
-        }
-        catch (NoSuchMethodException | SecurityException ignored) {
-            ctor = null;
-        }
-
-        try {
-            Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
-
-            for (int i = 0; i < row.size(); i++) {
-                Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
-
-                if (entityField != null)
-                    FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
-            }
-
-            return (V)res;
-        }
-        catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
-            throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
-        }
-    }
-
-    /**
-     * Validates operations that requires Pageable parameter
-     *
-     * @param returnStgy Return stgy.
-     * @param prmtrs     Prmtrs.
-     */
-    private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
-        try {
-            if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
-                || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
-                Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
-                page.isPaged();
-            }
-        }
-        catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
-            throw new IllegalStateException(
-                "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
-        }
-    }
-
-    /**
-     * Ignite QueryCursor wrapper.
-     * <p>
-     * Ensures closing underline cursor when there is no data.
-     *
-     * @param <T> input type
-     * @param <V> transformed output type
-     */
-    public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
-        /**
-         * Delegate query cursor.
-         */
-        private final QueryCursor<T> delegate;
-
-        /**
-         * Transformer.
-         */
-        private final Function<T, V> transformer;
-
-        /**
-         * Instantiates a new Query cursor wrapper.
-         *
-         * @param delegate    delegate QueryCursor with T input elements
-         * @param transformer Function to transform T to V elements
-         */
-        public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
-            this.delegate = delegate;
-            this.transformer = transformer;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Iterator<V> iterator() {
-            final Iterator<T> it = delegate.iterator();
-
-            return new Iterator<V>() {
-                /** */
-                @Override public boolean hasNext() {
-                    if (!it.hasNext()) {
-                        U.closeQuiet(delegate);
-                        return false;
-                    }
-                    return true;
-                }
-
-                /** */
-                @Override public V next() {
-                    final V r = transformer.apply(it.next());
-                    if (r != null)
-                        return r;
-                    throw new NoSuchElementException();
-                }
-            };
-        }
-
-        /** {@inheritDoc} */
-        @Override public void close() {
-            U.closeQuiet(delegate);
-        }
-
-        /** {@inheritDoc} */
-        @Override public List<V> getAll() {
-            final List<V> data = new ArrayList<>();
-            delegate.forEach(i -> data.add(transformer.apply(i)));
-            U.closeQuiet(delegate);
-            return data;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int size() {
-            return 0;
-        }
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java
deleted file mode 100644
index 40752b5..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/StringQuery.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.BiFunction;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext.SpelExtractor;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Range;
-import org.springframework.data.domain.Range.Bound;
-import org.springframework.data.repository.query.parser.Part.Type;
-import org.springframework.util.Assert;
-import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
-
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-import static org.springframework.util.ObjectUtils.nullSafeEquals;
-import static org.springframework.util.ObjectUtils.nullSafeHashCode;
-
-/**
- * Encapsulation of a JPA query String. Offers access to parameters as bindings. The internal query String is cleaned
- * from decorated parameters like {@literal %:lastname%} and the matching bindings take care of applying the decorations
- * in the {@link ParameterBinding#prepare(Object)} method. Note that this class also handles replacing SpEL expressions
- * with synthetic bind parameters
- *
- * @author Oliver Gierke
- * @author Thomas Darimont
- * @author Oliver Wehrens
- * @author Mark Paluch
- * @author Jens Schauder
- */
-class StringQuery implements DeclaredQuery {
-    /** */
-    private final String query;
-
-    /** */
-    private final List<ParameterBinding> bindings;
-
-    /** */
-    @Nullable
-    private final String alias;
-
-    /** */
-    private final boolean hasConstructorExpression;
-
-    /** */
-    private final boolean containsPageableInSpel;
-
-    /** */
-    private final boolean usesJdbcStyleParameters;
-
-    /**
-     * Creates a new {@link StringQuery} from the given JPQL query.
-     *
-     * @param query must not be {@literal null} or empty.
-     */
-    StringQuery(String query) {
-        Assert.hasText(query, "Query must not be null or empty!");
-
-        bindings = new ArrayList<>();
-        containsPageableInSpel = query.contains("#pageable");
-
-        Metadata queryMeta = new Metadata();
-        this.query = ParameterBindingParser.INSTANCE
-            .parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(query, bindings,
-                queryMeta);
-
-        usesJdbcStyleParameters = queryMeta.usesJdbcStyleParameters;
-        alias = QueryUtils.detectAlias(query);
-        hasConstructorExpression = QueryUtils.hasConstructorExpression(query);
-    }
-
-    /**
-     * Returns whether we have found some like bindings.
-     */
-    boolean hasParameterBindings() {
-        return !bindings.isEmpty();
-    }
-
-    /** */
-    String getProjection() {
-        return QueryUtils.getProjection(query);
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#getParameterBindings()
-    /** {@inheritDoc} */
-    @Override public List<ParameterBinding> getParameterBindings() {
-        return bindings;
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#deriveCountQuery(java.lang.String, java.lang
-    /** {@inheritDoc} */
-    @Override public DeclaredQuery deriveCountQuery(@Nullable String countQuery,
-        @Nullable String countQueryProjection) {
-        return DeclaredQuery
-            .of(countQuery != null ? countQuery : QueryUtils.createCountQueryFor(query, countQueryProjection));
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#usesJdbcStyleParameters()
-    /** */
-    @Override public boolean usesJdbcStyleParameters() {
-        return usesJdbcStyleParameters;
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#getQueryString()
-    /** {@inheritDoc} */
-    @Override public String getQueryString() {
-        return query;
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#getAlias()
-    /** {@inheritDoc} */
-    @Override @Nullable
-    public String getAlias() {
-        return alias;
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#hasConstructorExpression()
-    /** {@inheritDoc} */
-    @Override public boolean hasConstructorExpression() {
-        return hasConstructorExpression;
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#isDefaultProjection()
-    /** {@inheritDoc} */
-    @Override public boolean isDefaultProjection() {
-        return getProjection().equalsIgnoreCase(alias);
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#hasNamedParameter()
-    /** {@inheritDoc} */
-    @Override public boolean hasNamedParameter() {
-        return bindings.stream().anyMatch(b -> b.getName() != null);
-    }
-
-    // See org.springframework.data.jpa.repository.query.DeclaredQuery#usesPaging()
-    /** {@inheritDoc} */
-    @Override public boolean usesPaging() {
-        return containsPageableInSpel;
-    }
-
-    /**
-     * A parser that extracts the parameter bindings from a given query string.
-     *
-     * @author Thomas Darimont
-     */
-    enum ParameterBindingParser {
-        /** */
-        INSTANCE;
-
-        /** */
-        private static final String EXPRESSION_PARAMETER_PREFIX = "__$synthetic$__";
-
-        /** */
-        public static final String POSITIONAL_OR_INDEXED_PARAMETER = "\\?(\\d*+(?![#\\w]))";
-        // .....................................................................^ not followed by a hash or a letter.
-        // .................................................................^ zero or more digits.
-        // .............................................................^ start with a question mark.
-
-        /** */
-        private static final Pattern PARAMETER_BINDING_BY_INDEX = Pattern.compile(POSITIONAL_OR_INDEXED_PARAMETER);
-
-        /** */
-        private static final Pattern PARAMETER_BINDING_PATTERN;
-
-        /** */
-        private static final String MESSAGE =
-            "Already found parameter binding with same index / parameter name but differing binding type! "
-                + "Already have: %s, found %s! If you bind a parameter multiple times make sure they use the same "
-                + "binding.";
-
-        /** */
-        private static final int INDEXED_PARAMETER_GROUP = 4;
-
-        /** */
-        private static final int NAMED_PARAMETER_GROUP = 6;
-
-        /** */
-        private static final int COMPARISION_TYPE_GROUP = 1;
-
-        static {
-            List<String> keywords = new ArrayList<>();
-
-            for (ParameterBindingType type : ParameterBindingType.values()) {
-                if (type.getKeyword() != null) {
-                    keywords.add(type.getKeyword());
-                }
-            }
-
-            StringBuilder builder = new StringBuilder();
-            builder.append("(");
-            builder.append(StringUtils.collectionToDelimitedString(keywords, "|")); // keywords
-            builder.append(")?");
-            builder.append("(?: )?"); // some whitespace
-            builder.append("\\(?"); // optional braces around parameters
-            builder.append("(");
-            builder.append("%?(" + POSITIONAL_OR_INDEXED_PARAMETER + ")%?"); // position parameter and parameter index
-            builder.append("|"); // or
-
-            // named parameter and the parameter name
-            builder.append("%?(" + QueryUtils.COLON_NO_DOUBLE_COLON + QueryUtils.IDENTIFIER_GROUP + ")%?");
-
-            builder.append(")");
-            builder.append("\\)?"); // optional braces around parameters
-
-            PARAMETER_BINDING_PATTERN = Pattern.compile(builder.toString(), CASE_INSENSITIVE);
-        }
-
-        /**
-         * Parses {@link ParameterBinding} instances from the given query and adds them to the registered bindings.
-         * Returns the cleaned up query.
-         */
-        private String parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(String query,
-            List<ParameterBinding> bindings,
-            Metadata queryMeta) {
-            int greatestParamIdx = tryFindGreatestParameterIndexIn(query);
-            boolean parametersShouldBeAccessedByIdx = greatestParamIdx != -1;
-
-            /*
-             * Prefer indexed access over named parameters if only SpEL Expression parameters are present.
-             */
-            if (!parametersShouldBeAccessedByIdx && query.contains("?#{")) {
-                parametersShouldBeAccessedByIdx = true;
-                greatestParamIdx = 0;
-            }
-
-            SpelExtractor spelExtractor = createSpelExtractor(query, parametersShouldBeAccessedByIdx,
-                greatestParamIdx);
-
-            String resultingQry = spelExtractor.getQueryString();
-            Matcher matcher = PARAMETER_BINDING_PATTERN.matcher(resultingQry);
-            QuotationMap quotedAreas = new QuotationMap(resultingQry);
-
-            int expressionParamIdx = parametersShouldBeAccessedByIdx ? greatestParamIdx : 0;
-
-            boolean usesJpaStyleParameters = false;
-
-            while (matcher.find()) {
-                if (quotedAreas.isQuoted(matcher.start()))
-                    continue;
-
-                String paramIdxStr = matcher.group(INDEXED_PARAMETER_GROUP);
-                String paramName = paramIdxStr != null ? null : matcher.group(NAMED_PARAMETER_GROUP);
-                Integer paramIdx = getParameterIndex(paramIdxStr);
-
-                String typeSrc = matcher.group(COMPARISION_TYPE_GROUP);
-                String expression = spelExtractor
-                    .getParameter(paramName == null ? paramIdxStr : paramName);
-                String replacement = null;
-
-                Assert.isTrue(paramIdxStr != null || paramName != null,
-                    () -> String.format("We need either a name or an index! Offending query string: %s", query));
-
-                expressionParamIdx++;
-                if (paramIdxStr != null && paramIdxStr.isEmpty()) {
-                    queryMeta.usesJdbcStyleParameters = true;
-                    paramIdx = expressionParamIdx;
-                }
-                else
-                    usesJpaStyleParameters = true;
-
-                // named parameters (:param) will be untouched by spelExtractor, so replace them by ? as we don't
-                // know position
-                if (paramName != null)
-                    replacement = "?";
-
-                if (usesJpaStyleParameters && queryMeta.usesJdbcStyleParameters) {
-                    throw new IllegalArgumentException(
-                        "Mixing of ? (? or :myNamedParam) parameters and other forms like ?1 (SpEL espressions or "
-                            + "indexed) is not supported!. Please, if you are using expressions or "
-                            + "indexed params, replace all named parameters by expressions. Example :myNamedParam "
-                            + "by ?#{#myNamedParam}.");
-                }
-
-                switch (ParameterBindingType.of(typeSrc)) {
-                    case LIKE:
-                        Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2));
-                        replacement = matcher.group(3);
-
-                        if (paramIdx != null)
-                            checkAndRegister(new LikeParameterBinding(paramIdx, likeType, expression), bindings);
-                        else {
-                            checkAndRegister(new LikeParameterBinding(paramName, likeType, expression), bindings);
-
-                            replacement = expression != null ? ":" + paramName : matcher.group(5);
-                        }
-
-                        break;
-
-                    case IN:
-                        if (paramIdx != null)
-                            checkAndRegister(new InParameterBinding(paramIdx, expression), bindings);
-                        else
-                            checkAndRegister(new InParameterBinding(paramName, expression), bindings);
-
-                        break;
-
-                    case AS_IS: // fall-through we don't need a special parameter binding for the given parameter.
-                    default:
-                        bindings.add(paramIdx != null
-                            ? new ParameterBinding(null, paramIdx, expression)
-                            : new ParameterBinding(paramName, null, expression));
-                }
-
-                if (replacement != null)
-                    resultingQry = replaceFirst(resultingQry, matcher.group(2), replacement);
-            }
-
-            return resultingQry;
-        }
-
-        /** */
-        private static SpelExtractor createSpelExtractor(String queryWithSpel,
-            boolean parametersShouldBeAccessedByIndex,
-            int greatestParameterIndex) {
-
-            /*
-             * If parameters need to be bound by index, we bind the synthetic expression parameters starting from
-             * position of the greatest discovered index parameter in order to
-             * not mix-up with the actual parameter indices.
-             */
-            int expressionParameterIndex = parametersShouldBeAccessedByIndex ? greatestParameterIndex : 0;
-
-            BiFunction<Integer, String, String> indexToParameterName = parametersShouldBeAccessedByIndex
-                ? (index, expression) -> String.valueOf(
-                index + expressionParameterIndex + 1)
-                : (index, expression) ->
-                EXPRESSION_PARAMETER_PREFIX + (index
-                    + 1);
-
-            String fixedPrefix = parametersShouldBeAccessedByIndex ? "?" : ":";
-
-            BiFunction<String, String, String> parameterNameToReplacement = (prefix, name) -> fixedPrefix + name;
-
-            return SpelQueryContext.of(indexToParameterName, parameterNameToReplacement).parse(queryWithSpel);
-        }
-
-        /** */
-        private static String replaceFirst(String text, String substring, String replacement) {
-            int index = text.indexOf(substring);
-            if (index < 0)
-                return text;
-
-            return text.substring(0, index) + replacement + text.substring(index + substring.length());
-        }
-
-        /** */
-        @Nullable
-        private static Integer getParameterIndex(@Nullable String parameterIndexString) {
-            if (parameterIndexString == null || parameterIndexString.isEmpty())
-                return null;
-            return Integer.valueOf(parameterIndexString);
-        }
-
-        /** */
-        private static int tryFindGreatestParameterIndexIn(String query) {
-            Matcher parameterIndexMatcher = PARAMETER_BINDING_BY_INDEX.matcher(query);
-
-            int greatestParameterIndex = -1;
-            while (parameterIndexMatcher.find()) {
-
-                String parameterIndexString = parameterIndexMatcher.group(1);
-                Integer parameterIndex = getParameterIndex(parameterIndexString);
-                if (parameterIndex != null)
-                    greatestParameterIndex = Math.max(greatestParameterIndex, parameterIndex);
-            }
-
-            return greatestParameterIndex;
-        }
-
-        /** */
-        private static void checkAndRegister(ParameterBinding binding, List<ParameterBinding> bindings) {
-
-            bindings.stream() //
-                .filter(it -> it.hasName(binding.getName()) || it.hasPosition(binding.getPosition())) //
-                .forEach(it -> Assert.isTrue(it.equals(binding), String.format(MESSAGE, it, binding)));
-
-            if (!bindings.contains(binding))
-                bindings.add(binding);
-        }
-
-        /**
-         * An enum for the different types of bindings.
-         *
-         * @author Thomas Darimont
-         * @author Oliver Gierke
-         */
-        private enum ParameterBindingType {
-            // Trailing whitespace is intentional to reflect that the keywords must be used with at least one whitespace
-            // character, while = does not.
-            /** */
-            LIKE("like "),
-
-            /** */
-            IN("in "),
-
-            /** */
-            AS_IS(null);
-
-            /** */
-            @Nullable
-            private final String keyword;
-
-            /** */
-            ParameterBindingType(@Nullable String keyword) {
-                this.keyword = keyword;
-            }
-
-            /**
-             * Returns the keyword that will tirgger the binding type or {@literal null} if the type is not triggered by
-             * a keyword.
-             *
-             * @return the keyword
-             */
-            @Nullable
-            public String getKeyword() {
-                return keyword;
-            }
-
-            /**
-             * Return the appropriate {@link ParameterBindingType} for the given {@link String}. Returns {@literal
-             * #AS_IS} in case no other {@link ParameterBindingType} could be found.
-             */
-            static ParameterBindingType of(String typeSource) {
-                if (!StringUtils.hasText(typeSource))
-                    return AS_IS;
-
-                for (ParameterBindingType type : values()) {
-                    if (type.name().equalsIgnoreCase(typeSource.trim()))
-                        return type;
-                }
-
-                throw new IllegalArgumentException(String.format("Unsupported parameter binding type %s!", typeSource));
-            }
-        }
-    }
-
-    /**
-     * A generic parameter binding with name or position information.
-     *
-     * @author Thomas Darimont
-     */
-    static class ParameterBinding {
-        /** */
-        @Nullable
-        private final String name;
-
-        /** */
-        @Nullable
-        private final String expression;
-
-        /** */
-        @Nullable
-        private final Integer position;
-
-        /**
-         * Creates a new {@link ParameterBinding} for the parameter with the given position.
-         *
-         * @param position must not be {@literal null}.
-         */
-        ParameterBinding(Integer position) {
-            this(null, position, null);
-        }
-
-        /**
-         * Creates a new {@link ParameterBinding} for the parameter with the given name, position and expression
-         * information. Either {@literal name} or {@literal position} must be not {@literal null}.
-         *
-         * @param name       of the parameter may be {@literal null}.
-         * @param position   of the parameter may be {@literal null}.
-         * @param expression the expression to apply to any value for this parameter.
-         */
-        ParameterBinding(@Nullable String name, @Nullable Integer position, @Nullable String expression) {
-
-            if (name == null)
-                Assert.notNull(position, "Position must not be null!");
-
-            if (position == null)
-                Assert.notNull(name, "Name must not be null!");
-
-            this.name = name;
-            this.position = position;
-            this.expression = expression;
-        }
-
-        /**
-         * Returns whether the binding has the given name. Will always be {@literal false} in case the {@link
-         * ParameterBinding} has been set up from a position.
-         */
-        boolean hasName(@Nullable String name) {
-            return position == null && this.name != null && this.name.equals(name);
-        }
-
-        /**
-         * Returns whether the binding has the given position. Will always be {@literal false} in case the {@link
-         * ParameterBinding} has been set up from a name.
-         */
-        boolean hasPosition(@Nullable Integer position) {
-            return position != null && name == null && position.equals(this.position);
-        }
-
-        /**
-         * @return the name
-         */
-        @Nullable
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * @return the name
-         * @throws IllegalStateException if the name is not available.
-         */
-        String getRequiredName() throws IllegalStateException {
-
-            String name = getName();
-
-            if (name != null)
-                return name;
-
-            throw new IllegalStateException(String.format("Required name for %s not available!", this));
-        }
-
-        /**
-         * @return the position
-         */
-        @Nullable
-        Integer getPosition() {
-            return position;
-        }
-
-        /**
-         * @return the position
-         * @throws IllegalStateException if the position is not available.
-         */
-        int getRequiredPosition() throws IllegalStateException {
-
-            Integer position = getPosition();
-
-            if (position != null)
-                return position;
-
-            throw new IllegalStateException(String.format("Required position for %s not available!", this));
-        }
-
-        /**
-         * @return {@literal true} if this parameter binding is a synthetic SpEL expression.
-         */
-        public boolean isExpression() {
-            return expression != null;
-        }
-
-        /** */
-        @Override public int hashCode() {
-
-            int result = 17;
-
-            result += nullSafeHashCode(name);
-            result += nullSafeHashCode(position);
-            result += nullSafeHashCode(expression);
-
-            return result;
-        }
-
-        /** */
-        @Override public boolean equals(Object obj) {
-
-            if (!(obj instanceof ParameterBinding))
-                return false;
-
-            ParameterBinding that = (ParameterBinding)obj;
-
-            return nullSafeEquals(name, that.name) && nullSafeEquals(position, that.position)
-                && nullSafeEquals(expression, that.expression);
-        }
-
-        /** */
-        @Override public String toString() {
-            return String.format("ParameterBinding [name: %s, position: %d, expression: %s]", getName(), getPosition(),
-                getExpression());
-        }
-
-        /**
-         * @param valueToBind value to prepare
-         */
-        @Nullable
-        public Object prepare(@Nullable Object valueToBind) {
-            return valueToBind;
-        }
-
-        /** */
-        @Nullable
-        public String getExpression() {
-            return expression;
-        }
-    }
-
-    /**
-     * Represents a {@link ParameterBinding} in a JPQL query augmented with instructions of how to apply a parameter as
-     * an {@code IN} parameter.
-     *
-     * @author Thomas Darimont
-     */
-    static class InParameterBinding extends ParameterBinding {
-        /**
-         * Creates a new {@link InParameterBinding} for the parameter with the given name.
-         */
-        InParameterBinding(String name, @Nullable String expression) {
-            super(name, null, expression);
-        }
-
-        /**
-         * Creates a new {@link InParameterBinding} for the parameter with the given position.
-         */
-        InParameterBinding(int position, @Nullable String expression) {
-            super(null, position, expression);
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see org.springframework.data.jpa.repository.query.StringQuery.ParameterBinding#prepare(java.lang.Object)
-         */
-        @Override public Object prepare(@Nullable Object value) {
-            if (!ObjectUtils.isArray(value))
-                return value;
-
-            int length = Array.getLength(value);
-            Collection<Object> result = new ArrayList<>(length);
-
-            for (int i = 0; i < length; i++)
-                result.add(Array.get(value, i));
-
-            return result;
-        }
-
-    }
-
-    /**
-     * Represents a parameter binding in a JPQL query augmented with instructions of how to apply a parameter as LIKE
-     * parameter. This allows expressions like {@code …like %?1} in the JPQL query, which is not allowed by plain JPA.
-     *
-     * @author Oliver Gierke
-     * @author Thomas Darimont
-     */
-    static class LikeParameterBinding extends ParameterBinding {
-        /** */
-        private static final List<Type> SUPPORTED_TYPES = Arrays.asList(Type.CONTAINING, Type.STARTING_WITH,
-            Type.ENDING_WITH, Type.LIKE);
-
-        /** */
-        private final Type type;
-
-        /**
-         * Creates a new {@link LikeParameterBinding} for the parameter with the given name and {@link Type}.
-         *
-         * @param name must not be {@literal null} or empty.
-         * @param type must not be {@literal null}.
-         */
-        LikeParameterBinding(String name, Type type) {
-            this(name, type, null);
-        }
-
-        /**
-         * Creates a new {@link LikeParameterBinding} for the parameter with the given name and {@link Type} and
-         * parameter binding input.
-         *
-         * @param name       must not be {@literal null} or empty.
-         * @param type       must not be {@literal null}.
-         * @param expression may be {@literal null}.
-         */
-        LikeParameterBinding(String name, Type type, @Nullable String expression) {
-
-            super(name, null, expression);
-
-            Assert.hasText(name, "Name must not be null or empty!");
-            Assert.notNull(type, "Type must not be null!");
-
-            Assert.isTrue(SUPPORTED_TYPES.contains(type), String.format("Type must be one of %s!",
-                StringUtils.collectionToCommaDelimitedString(SUPPORTED_TYPES)));
-
-            this.type = type;
-        }
-
-        /**
-         * Creates a new {@link LikeParameterBinding} for the parameter with the given position and {@link Type}.
-         *
-         * @param position position of the parameter in the query.
-         * @param type     must not be {@literal null}.
-         */
-        LikeParameterBinding(int position, Type type) {
-            this(position, type, null);
-        }
-
-        /**
-         * Creates a new {@link LikeParameterBinding} for the parameter with the given position and {@link Type}.
-         *
-         * @param position   position of the parameter in the query.
-         * @param type       must not be {@literal null}.
-         * @param expression may be {@literal null}.
-         */
-        LikeParameterBinding(int position, Type type, @Nullable String expression) {
-
-            super(null, position, expression);
-
-            Assert.isTrue(position > 0, "Position must be greater than zero!");
-            Assert.notNull(type, "Type must not be null!");
-
-            Assert.isTrue(SUPPORTED_TYPES.contains(type), String.format("Type must be one of %s!",
-                StringUtils.collectionToCommaDelimitedString(SUPPORTED_TYPES)));
-
-            this.type = type;
-        }
-
-        /**
-         * Returns the {@link Type} of the binding.
-         *
-         * @return the type
-         */
-        public Type getType() {
-            return type;
-        }
-
-        /**
-         * Prepares the given raw keyword according to the like type.
-         */
-        @Nullable
-        @Override public Object prepare(@Nullable Object value) {
-            if (value == null)
-                return null;
-
-            switch (type) {
-                case STARTING_WITH:
-                    return String.format("%s%%", value.toString());
-                case ENDING_WITH:
-                    return String.format("%%%s", value.toString());
-                case CONTAINING:
-                    return String.format("%%%s%%", value.toString());
-                case LIKE:
-                default:
-                    return value;
-            }
-        }
-
-        /** */
-        @Override public boolean equals(Object obj) {
-            if (!(obj instanceof LikeParameterBinding))
-                return false;
-
-            LikeParameterBinding that = (LikeParameterBinding)obj;
-
-            return super.equals(obj) && type.equals(that.type);
-        }
-
-        /** */
-        @Override public int hashCode() {
-
-            int result = super.hashCode();
-
-            result += nullSafeHashCode(type);
-
-            return result;
-        }
-
-        /** */
-        @Override public String toString() {
-            return String.format("LikeBinding [name: %s, position: %d, type: %s]", getName(), getPosition(), type);
-        }
-
-        /**
-         * Extracts the like {@link Type} from the given JPA like expression.
-         *
-         * @param expression must not be {@literal null} or empty.
-         */
-        private static Type getLikeTypeFrom(String expression) {
-
-            Assert.hasText(expression, "Expression must not be null or empty!");
-
-            if (expression.matches("%.*%"))
-                return Type.CONTAINING;
-
-            if (expression.startsWith("%"))
-                return Type.ENDING_WITH;
-
-            if (expression.endsWith("%"))
-                return Type.STARTING_WITH;
-
-            return Type.LIKE;
-        }
-
-    }
-
-    /** */
-    static class Metadata {
-        /**
-         * Uses jdbc style parameters.
-         */
-        private boolean usesJdbcStyleParameters;
-    }
-
-    /**
-     * Value object to analyze a {@link String} to determine the parts of the {@link String} that are quoted and offers
-     * an API to query that information.
-     *
-     * @author Jens Schauder
-     * @author Oliver Gierke
-     */
-    static class QuotationMap {
-        /** */
-        private static final Collection<Character> QUOTING_CHARACTERS = Arrays.asList('"', '\'');
-
-        /** */
-        private final List<Range<Integer>> quotedRanges = new ArrayList<>();
-
-        /**
-         * Creates a new instance for the query.
-         *
-         * @param query can be {@literal null}.
-         */
-        public QuotationMap(@Nullable String query) {
-            if (query == null)
-                return;
-
-            Character inQuotation = null;
-            int start = 0;
-
-            for (int i = 0; i < query.length(); i++) {
-                char currentChar = query.charAt(i);
-
-                if (QUOTING_CHARACTERS.contains(currentChar)) {
-                    if (inQuotation == null) {
-
-                        inQuotation = currentChar;
-                        start = i;
-                    }
-                    else if (currentChar == inQuotation) {
-                        inQuotation = null;
-
-                        quotedRanges.add(Range.from(Bound.inclusive(start)).to(Bound.inclusive(i)));
-                    }
-                }
-            }
-
-            if (inQuotation != null) {
-                throw new IllegalArgumentException(
-                    String.format("The string <%s> starts a quoted range at %d, but never ends it.", query, start));
-            }
-        }
-
-        /**
-         * Checks if a given index is within a quoted range.
-         *
-         * @param idx to check if it is part of a quoted range.
-         * @return whether the query contains a quoted range at {@literal index}.
-         */
-        public boolean isQuoted(int idx) {
-            return quotedRanges.stream().anyMatch(r -> r.contains(idx));
-        }
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java
deleted file mode 100644
index c9f90dc..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes classes that integrates with Apache Ignite SQL engine.
- */
-package org.apache.ignite.springdata20.repository.query;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java
deleted file mode 100644
index c442b68..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelEvaluator.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query.spel;
-
-import java.util.Map;
-import java.util.stream.Collectors;
-import org.apache.ignite.springdata20.repository.query.spel.SpelQueryContext.SpelExtractor;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.Assert;
-
-/**
- * Evaluates SpEL expressions as extracted by the {@link SpelExtractor} based on parameter information from a method and
- * parameter values from a method call.
- *
- * @author Jens Schauder
- * @author Gerrit Meier
- * @author Oliver Gierke
- */
-public class SpelEvaluator {
-    /** */
-    private static final SpelExpressionParser PARSER = new SpelExpressionParser();
-
-    /** */
-    private final EvaluationContextProvider evaluationCtxProvider;
-
-    /** */
-    private final Parameters<?, ?> parameters;
-
-    /** */
-    private final SpelExtractor extractor;
-
-    /**
-     * @param evaluationCtxProvider Evaluation context provider.
-     * @param parameters            Parameters.
-     * @param extractor             Extractor.
-     */
-    public SpelEvaluator(EvaluationContextProvider evaluationCtxProvider,
-        Parameters<?, ?> parameters,
-        SpelExtractor extractor) {
-        this.evaluationCtxProvider = evaluationCtxProvider;
-        this.parameters = parameters;
-        this.extractor = extractor;
-    }
-
-    /**
-     * Evaluate all the SpEL expressions in {@link #parameters} based on values provided as an argument.
-     *
-     * @param values Parameter values. Must not be {@literal null}.
-     * @return a map from parameter name to evaluated value. Guaranteed to be not {@literal null}.
-     */
-    public Map<String, Object> evaluate(Object[] values) {
-        Assert.notNull(values, "Values must not be null.");
-
-        EvaluationContext evaluationCtx = evaluationCtxProvider.getEvaluationContext(parameters, values);
-
-        return extractor.getParameters().collect(Collectors.toMap(//
-            Map.Entry::getKey, //
-            it -> getSpElValue(evaluationCtx, it.getValue()) //
-        ));
-    }
-
-    /**
-     * Returns the query string produced by the intermediate SpEL expression collection step.
-     *
-     * @return the query string produced by the intermediate SpEL expression collection step
-     */
-    public String getQueryString() {
-        return extractor.getQueryString();
-    }
-
-    /**
-     * @param evaluationCtx Evaluation context.
-     * @param expression    Expression.
-     */
-    @Nullable
-    private static Object getSpElValue(EvaluationContext evaluationCtx, String expression) {
-        return PARSER.parseExpression(expression).getValue(evaluationCtx);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java
deleted file mode 100644
index 44bfec8..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/spel/SpelQueryContext.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.query.spel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.BiFunction;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Range;
-import org.springframework.data.domain.Range.Bound;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.util.Assert;
-
-/**
- * Source of {@link SpelExtractor} encapsulating configuration often common for all queries.
- *
- * @author Jens Schauder
- * @author Gerrit Meier
- */
-public class SpelQueryContext {
-    /** */
-    private static final String SPEL_PATTERN_STRING = "([:?])#\\{([^}]+)}";
-
-    /** */
-    private static final Pattern SPEL_PATTERN = Pattern.compile(SPEL_PATTERN_STRING);
-
-    /**
-     * A function from the index of a SpEL expression in a query and the actual SpEL expression to the parameter name to
-     * be used in place of the SpEL expression. A typical implementation is expected to look like
-     * <code>(index, spel) -> "__some_placeholder_" + index</code>
-     */
-    private final BiFunction<Integer, String, String> paramNameSrc;
-
-    /**
-     * A function from a prefix used to demarcate a SpEL expression in a query and a parameter name as returned from
-     * {@link #paramNameSrc} to a {@literal String} to be used as a replacement of the SpEL in the query. The returned
-     * value should normally be interpretable as a bind parameter by the underlying persistence mechanism. A typical
-     * implementation is expected to look like <code>(prefix, name) -> prefix + name</code> or
-     * <code>(prefix, name) -> "{" + name + "}"</code>
-     */
-    private final BiFunction<String, String, String> replacementSrc;
-
-    /** */
-    private SpelQueryContext(BiFunction<Integer, String, String> paramNameSrc,
-        BiFunction<String, String, String> replacementSrc) {
-        this.paramNameSrc = paramNameSrc;
-        this.replacementSrc = replacementSrc;
-    }
-
-    /**
-     * Of spel query context.
-     *
-     * @param parameterNameSource the parameter name source
-     * @param replacementSource   the replacement source
-     * @return the spel query context
-     */
-    public static SpelQueryContext of(BiFunction<Integer, String, String> parameterNameSource,
-        BiFunction<String, String, String> replacementSource) {
-        return new SpelQueryContext(parameterNameSource, replacementSource);
-    }
-
-    /**
-     * Parses the query for SpEL expressions using the pattern:
-     *
-     * <pre>
-     * &lt;prefix&gt;#{&lt;spel&gt;}
-     * </pre>
-     * <p>
-     * with prefix being the character ':' or '?'. Parsing honors quoted {@literal String}s enclosed in single or double
-     * quotation marks.
-     *
-     * @param qry a query containing SpEL expressions in the format described above. Must not be {@literal null}.
-     * @return A {@link SpelExtractor} which makes the query with SpEL expressions replaced by bind parameters and a map
-     * from bind parameter to SpEL expression available. Guaranteed to be not {@literal null}.
-     */
-    public SpelExtractor parse(String qry) {
-        return new SpelExtractor(qry);
-    }
-
-    /**
-     * Createsa {@link EvaluatingSpelQueryContext} from the current one and the given {@link
-     * EvaluationContextProvider}*.
-     *
-     * @param provider must not be {@literal null}.
-     * @return Evaluating Spel QueryContext
-     */
-    public EvaluatingSpelQueryContext withEvaluationContextProvider(EvaluationContextProvider provider) {
-        Assert.notNull(provider, "EvaluationContextProvider must not be null!");
-
-        return new EvaluatingSpelQueryContext(provider, paramNameSrc, replacementSrc);
-    }
-
-    /**
-     * An extension of {@link SpelQueryContext} that can create {@link SpelEvaluator} instances as it also knows about a
-     * {@link EvaluationContextProvider}.
-     *
-     * @author Oliver Gierke
-     */
-    public static class EvaluatingSpelQueryContext extends SpelQueryContext {
-        /** */
-        private final EvaluationContextProvider evaluationContextProvider;
-
-        /**
-         * Creates a new {@link EvaluatingSpelQueryContext} for the given {@link EvaluationContextProvider}, parameter
-         * name source and replacement source.
-         *
-         * @param evaluationCtxProvider must not be {@literal null}.
-         * @param paramNameSrc          must not be {@literal null}.
-         * @param replacementSrc        must not be {@literal null}.
-         */
-        private EvaluatingSpelQueryContext(EvaluationContextProvider evaluationCtxProvider,
-            BiFunction<Integer, String, String> paramNameSrc, BiFunction<String, String, String> replacementSrc) {
-            super(paramNameSrc, replacementSrc);
-
-            evaluationContextProvider = evaluationCtxProvider;
-        }
-
-        /**
-         * Parses the query for SpEL expressions using the pattern:
-         *
-         * <pre>
-         * &lt;prefix&gt;#{&lt;spel&gt;}
-         * </pre>
-         * <p>
-         * with prefix being the character ':' or '?'. Parsing honors quoted {@literal String}s enclosed in single or
-         * double quotation marks.
-         *
-         * @param qry        a query containing SpEL expressions in the format described above. Must not be {@literal
-         *                   null}.
-         * @param parameters a {@link Parameters} instance describing query method parameters
-         * @return A {@link SpelEvaluator} which allows to evaluate the SpEL expressions. Will never be {@literal null}.
-         */
-        public SpelEvaluator parse(String qry, Parameters<?, ?> parameters) {
-            return new SpelEvaluator(evaluationContextProvider, parameters, parse(qry));
-        }
-    }
-
-    /**
-     * Parses a query string, identifies the contained SpEL expressions, replaces them with bind parameters and offers a
-     * {@link Map} from those bind parameters to the spel expression.
-     * <p>
-     * The parser detects quoted parts of the query string and does not detect SpEL expressions inside such quoted parts
-     * of the query.
-     *
-     * @author Jens Schauder
-     * @author Oliver Gierke
-     */
-    public class SpelExtractor {
-        /** */
-        private static final int PREFIX_GROUP_INDEX = 1;
-
-        /** */
-        private static final int EXPRESSION_GROUP_INDEX = 2;
-
-        /** */
-        private final String query;
-
-        /** */
-        private final Map<String, String> expressions;
-
-        /** */
-        private final QuotationMap quotations;
-
-        /**
-         * Creates a SpelExtractor from a query String.
-         *
-         * @param qry must not be {@literal null}.
-         */
-        SpelExtractor(String qry) {
-            Assert.notNull(qry, "Query must not be null");
-
-            Map<String, String> exps = new HashMap<>();
-            Matcher matcher = SPEL_PATTERN.matcher(qry);
-            StringBuilder resultQry = new StringBuilder();
-            QuotationMap quotedAreas = new QuotationMap(qry);
-
-            int expressionCounter = 0;
-            int matchedUntil = 0;
-
-            while (matcher.find()) {
-                if (quotedAreas.isQuoted(matcher.start()))
-                    resultQry.append(qry, matchedUntil, matcher.end());
-
-                else {
-                    String spelExpression = matcher.group(EXPRESSION_GROUP_INDEX);
-                    String prefix = matcher.group(PREFIX_GROUP_INDEX);
-
-                    String paramName = paramNameSrc.apply(expressionCounter, spelExpression);
-                    String replacement = replacementSrc.apply(prefix, paramName);
-
-                    resultQry.append(qry, matchedUntil, matcher.start());
-                    resultQry.append(replacement);
-
-                    exps.put(paramName, spelExpression);
-                    expressionCounter++;
-                }
-
-                matchedUntil = matcher.end();
-            }
-
-            resultQry.append(qry.substring(matchedUntil));
-
-            expressions = Collections.unmodifiableMap(exps);
-            query = resultQry.toString();
-            quotations = quotedAreas;
-        }
-
-        /**
-         * The query with all the SpEL expressions replaced with bind parameters.
-         *
-         * @return Guaranteed to be not {@literal null}.
-         */
-        public String getQueryString() {
-            return query;
-        }
-
-        /**
-         * Is quoted.
-         *
-         * @param idx the idx
-         * @return the boolean
-         */
-        public boolean isQuoted(int idx) {
-            return quotations.isQuoted(idx);
-        }
-
-        /**
-         * Gets parameter.
-         *
-         * @param name the name
-         * @return the parameter
-         */
-        public String getParameter(String name) {
-            return expressions.get(name);
-        }
-
-        /**
-         * A {@literal Map} from parameter name to SpEL expression.
-         *
-         * @return Guaranteed to be not {@literal null}.
-         */
-        Map<String, String> getParameterMap() {
-            return expressions;
-        }
-
-        /**
-         * Gets parameters.
-         *
-         * @return the parameters
-         */
-        Stream<Entry<String, String>> getParameters() {
-            return expressions.entrySet().stream();
-        }
-    }
-
-    /**
-     * Value object to analyze a {@link String} to determine the parts of the {@link String} that are quoted and offers
-     * an API to query that information.
-     *
-     * @author Jens Schauder
-     * @author Oliver Gierke
-     */
-    static class QuotationMap {
-        /** */
-        private static final Collection<Character> QUOTING_CHARACTERS = Arrays.asList('"', '\'');
-
-        /** */
-        private final List<Range<Integer>> quotedRanges = new ArrayList<>();
-
-        /**
-         * Creates a new {@link QuotationMap} for the query.
-         *
-         * @param qry can be {@literal null}.
-         */
-        public QuotationMap(@Nullable String qry) {
-            if (qry == null)
-                return;
-
-            Character inQuotation = null;
-            int start = 0;
-
-            for (int i = 0; i < qry.length(); i++) {
-
-                char curChar = qry.charAt(i);
-
-                if (QUOTING_CHARACTERS.contains(curChar)) {
-
-                    if (inQuotation == null) {
-
-                        inQuotation = curChar;
-                        start = i;
-
-                    }
-                    else if (curChar == inQuotation) {
-
-                        inQuotation = null;
-
-                        quotedRanges.add(Range.from(Bound.inclusive(start)).to(Bound.inclusive(i)));
-                    }
-                }
-            }
-
-            if (inQuotation != null) {
-                throw new IllegalArgumentException(
-                    String.format("The string <%s> starts a quoted range at %d, but never ends it.", qry, start));
-            }
-        }
-
-        /**
-         * Checks if a given index is within a quoted range.
-         *
-         * @param idx to check if it is part of a quoted range.
-         * @return whether the query contains a quoted range at {@literal index}.
-         */
-        public boolean isQuoted(int idx) {
-            return quotedRanges.stream().anyMatch(r -> r.contains(idx));
-        }
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java
deleted file mode 100644
index 1b4b378..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/ConditionFalse.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import org.springframework.context.annotation.Condition;
-import org.springframework.context.annotation.ConditionContext;
-import org.springframework.core.type.AnnotatedTypeMetadata;
-
-/**
- * Always false condition. Tells spring context never load bean with such Condition.
- */
-public class ConditionFalse implements Condition {
-    /** {@inheritDoc} */
-    @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
-        return false;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java
deleted file mode 100644
index b5280ee..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteProxyFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.config.BeanExpressionResolver;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-
-import static org.apache.ignite.springdata20.repository.support.IgniteRepositoryFactory.getRepositoryConfiguration;
-
-/**
- * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
- * Ignite cluster.
- */
-public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
-    /** Spring application expression resolver. */
-    private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
-
-    /** Repositories associated with Ignite proxy. */
-    private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
-
-    /** Spring application context. */
-    private ApplicationContext ctx;
-
-    /** Spring application bean expression context. */
-    private BeanExpressionContext beanExpressionCtx;
-
-    /**
-     * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
-     * @return {@link IgniteProxy} instance.
-     */
-    public IgniteProxy igniteProxy(Class<?> repoInterface) {
-        return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
-        this.ctx = ctx;
-
-        beanExpressionCtx = new BeanExpressionContext(
-            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
-            null);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void destroy() throws Exception {
-        Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
-
-        Exception destroyE = null;
-
-        for (IgniteProxy proxy : proxies) {
-            if (proxy instanceof AutoCloseable) {
-                try {
-                    ((AutoCloseable)proxy).close();
-                }
-                catch (Exception e) {
-                    if (destroyE == null)
-                        destroyE = e;
-                    else
-                        destroyE.addSuppressed(e);
-                }
-            }
-        }
-
-        if (destroyE != null)
-            throw destroyE;
-    }
-
-    /**
-     * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
-     *
-     * @param repoInterface {@link Class} instance of the repository interface.
-     * @return Instance of {@link IgniteProxy} associated with specified repository.
-     *
-     * @see RepositoryConfig
-     */
-    private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
-        RepositoryConfig repoCfg = getRepositoryConfiguration(repoInterface);
-
-        return Stream.<BeanFinder>of(
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
-            () -> ctx.getBean(Ignite.class),
-            () -> ctx.getBean(IgniteClient.class),
-            () -> ctx.getBean(IgniteConfiguration.class),
-            () -> ctx.getBean(ClientConfiguration.class)
-        ).map(BeanFinder::getBean)
-            .filter(Objects::nonNull)
-            .findFirst()
-            .map(IgniteProxy::of)
-            .orElseThrow(() -> {
-                return new IllegalArgumentException("Invalid configuration for repository " +
-                    repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
-                    " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
-                    " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
-                    " ClientConfiguration or IgniteConfiguration bean to application context.");
-            });
-    }
-
-    /**
-     * Evaluates the SpEL expression.
-     *
-     * @param spelExpression SpEL expression
-     * @return The result of evaluation of the SpEL expression.
-     */
-    private String evaluateExpression(String spelExpression) {
-        return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
-    }
-
-    /**
-     * Helper interface that wraps getBean method.
-     */
-    @FunctionalInterface
-    private interface BeanFinder {
-        /**
-         * Get bean.
-         * @return Bean or null if {@link BeansException} was thrown.
-         */
-        default Object getBean() {
-            try {
-                return get();
-            } catch (BeansException ex) {
-                return null;
-            }
-        }
-
-        /**
-         * Get bean.
-         * @return Bean.
-         * @throws BeansException If bean was not found.
-         */
-        Object get() throws BeansException;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java
deleted file mode 100644
index 2096277..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactory.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.support;
-
-import java.util.Optional;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata20.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata20.repository.query.IgniteQuery;
-import org.apache.ignite.springdata20.repository.query.IgniteQueryGenerator;
-import org.apache.ignite.springdata20.repository.query.IgniteRepositoryQuery;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.RepositoryInformation;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.core.support.AbstractEntityInformation;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.EvaluationContextProvider;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * Crucial for spring-data functionality class. Create proxies for repositories.
- * <p>
- * Supports multiple Ignite Instances on same JVM.
- * <p>
- * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteRepositoryFactory extends RepositoryFactorySupport {
-    /** Spring application expression resolver */
-    private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
-
-    /** Spring application bean expression context */
-    private final BeanExpressionContext beanExpressionContext;
-
-    /** Ignite cache proxy instance associated with the current repository. */
-    private final IgniteCacheProxy<?, ?> cache;
-
-    /** Ignite proxy instance associated with the current repository. */
-    private final IgniteProxy ignite;
-
-    /**
-     * @param ctx Spring Application context.
-     * @param repoInterface Repository interface.
-     */
-    public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
-        ignite = ctx.getBean(IgniteProxy.class, repoInterface);
-
-        beanExpressionContext = new BeanExpressionContext(
-            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
-            null);
-
-        RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
-
-        String cacheName = evaluateExpression(cfg.cacheName());
-
-        Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
-            ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
-            " annotation to map this repository to the underlying cache.");
-
-       cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
-
-        if (cache == null) {
-            throw new IllegalArgumentException(
-                "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
-                    + ". Please, add a cache configuration to ignite configuration"
-                    + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
-        return new AbstractEntityInformation<T, ID>(domainClass) {
-            /** {@inheritDoc} */
-            @Override public ID getId(T entity) {
-                return null;
-            }
-
-            /** {@inheritDoc} */
-            @Override public Class<ID> getIdType() {
-                return null;
-            }
-        };
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
-        return IgniteRepositoryImpl.class;
-    }
-
-    /**
-     * Evaluate the SpEL expression
-     *
-     * @param spelExpression SpEL expression
-     * @return the result of execution of the SpEL expression
-     */
-    private String evaluateExpression(String spelExpression) {
-        return (String)resolver.evaluate(spelExpression, beanExpressionContext);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Object getTargetRepository(RepositoryInformation metadata) {
-        return getTargetRepositoryViaReflection(metadata, ignite, cache);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
-        EvaluationContextProvider evaluationContextProvider) {
-        return Optional.of((mtd, metadata, factory, namedQueries) -> {
-            final Query annotation = mtd.getAnnotation(Query.class);
-            if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
-                .dynamicQuery())) {
-
-                String qryStr = annotation.value();
-
-                boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
-                    .textQuery());
-
-                IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
-                    !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
-                    annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
-
-                if (key != QueryLookupStrategy.Key.CREATE) {
-                    return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
-                        annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
-                        evaluationContextProvider);
-                }
-            }
-
-            if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
-                throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
-                    + "a query string via org.apache.ignite.springdata20.repository"
-                    + ".config.Query annotation.");
-            }
-
-            return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
-                cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
-        });
-    }
-
-    /**
-     * @param qry Query string.
-     * @return {@code true} if query is SqlFieldsQuery.
-     */
-    public static boolean isFieldQuery(String qry) {
-        String qryUpperCase = qry.toUpperCase();
-
-        return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
-    }
-
-    /**
-     * Evaluates if the query starts with a clause.<br>
-     * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
-     *
-     * @param qryUpperCase Query string in upper case.
-     * @return {@code true} if query is full SQL statement.
-     */
-    private static boolean isStatement(String qryUpperCase) {
-        return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
-            // update
-            qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
-            // delete
-            qryUpperCase.matches("^\\s*DELETE\\b.*") ||
-            // merge
-            qryUpperCase.matches("^\\s*MERGE\\b.*") ||
-            // insert
-            qryUpperCase.matches("^\\s*INSERT\\b.*");
-    }
-
-    /**
-     * @return Configuration of the specified repository.
-     * @throws IllegalArgumentException If no configuration is specified.
-     * @see RepositoryConfig
-     */
-    static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
-        RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
-
-        Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
-            RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
-
-        return cfg;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java
deleted file mode 100644
index 0ec1313..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryFactoryBean.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata20.repository.support;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-
-/**
- * Apache Ignite repository factory bean.
- * <p>
- * The {@link org.apache.ignite.springdata20.repository.config.RepositoryConfig} requires to define one of the
- * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
- * <ul/>
- *
- * @param <T> Repository type, {@link IgniteRepository}
- * @param <V> Domain object class.
- * @param <K> Domain object key, super expects {@link Serializable}.
- */
-public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
-    extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
-    /** */
-    private ApplicationContext ctx;
-
-    /**
-     * @param repoInterface Repository interface.
-     */
-    protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
-        super(repoInterface);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
-        this.ctx = ctx;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected RepositoryFactorySupport createRepositoryFactory() {
-        return new IgniteRepositoryFactory(ctx, getObjectType());
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java
deleted file mode 100644
index b3e449a..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/IgniteRepositoryImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata20.repository.support;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.cache.Cache;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CachePeekMode;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.context.annotation.Conditional;
-
-/**
- * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
- * {@link IgniteRepositoryFactory}
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Conditional(ConditionFalse.class)
-public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
-    /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
-    private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
-        " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
-
-    /**
-     * Ignite Cache bound to the repository
-     */
-    private final IgniteCacheProxy<K, V> cache;
-
-    /**
-     * Ignite instance bound to the repository
-     */
-    private final IgniteProxy ignite;
-
-    /**
-     * Repository constructor.
-     *
-     * @param ignite the ignite
-     * @param cache  Initialized cache instance.
-     */
-    public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
-        this.cache = cache;
-        this.ignite = ignite;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteCache<K, V> cache() {
-        if (cache instanceof IgniteNodeCacheProxy)
-            return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
-
-        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
-    }
-
-    /** {@inheritDoc} */
-    @Override public Ignite ignite() {
-        if (ignite instanceof IgniteNodeProxy)
-            return ((IgniteNodeProxy)ignite).delegate();
-
-        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> S save(K key, S entity) {
-        cache.put(key, entity);
-
-        return entity;
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
-        cache.putAll(entities);
-
-        return entities.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
-        if (expiryPlc != null)
-            cache.withExpiryPolicy(expiryPlc).put(key, entity);
-        else
-            cache.put(key, entity);
-        return entity;
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
-        if (expiryPlc != null)
-            cache.withExpiryPolicy(expiryPlc).putAll(entities);
-        else
-            cache.putAll(entities);
-        return entities.values();
-    }
-
-    /**
-     * Not implemented.
-     */
-    @Override public <S extends V> S save(S entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
-    }
-
-    /**
-     * Not implemented.
-     */
-    @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
-        throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public Optional<V> findById(K id) {
-        return Optional.ofNullable(cache.get(id));
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean existsById(K id) {
-        return cache.containsKey(id);
-    }
-
-    /** {@inheritDoc} */
-    @Override public Iterable<V> findAll() {
-        final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
-
-        return new Iterable<V>() {
-            /** */
-            @Override public Iterator<V> iterator() {
-                return new Iterator<V>() {
-                    /** {@inheritDoc} */
-                    @Override public boolean hasNext() {
-                        return iter.hasNext();
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override public V next() {
-                        return iter.next().getValue();
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override public void remove() {
-                        iter.remove();
-                    }
-                };
-            }
-        };
-    }
-
-    /** {@inheritDoc} */
-    @Override public Iterable<V> findAllById(Iterable<K> ids) {
-        if (ids instanceof Set)
-            return cache.getAll((Set<K>)ids).values();
-
-        if (ids instanceof Collection)
-            return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
-
-        TreeSet<K> keys = new TreeSet<>();
-
-        for (K id : ids)
-            keys.add(id);
-
-        return cache.getAll(keys).values();
-    }
-
-    /** {@inheritDoc} */
-    @Override public long count() {
-        return cache.size(CachePeekMode.PRIMARY);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteById(K id) {
-        cache.remove(id);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void delete(V entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAll(Iterable<? extends V> entities) {
-        throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAllById(Iterable<K> ids) {
-        if (ids instanceof Set) {
-            cache.removeAll((Set<K>)ids);
-            return;
-        }
-
-        if (ids instanceof Collection) {
-            cache.removeAll(new HashSet<>((Collection<K>)ids));
-            return;
-        }
-
-        TreeSet<K> keys = new TreeSet<>();
-
-        for (K id : ids)
-            keys.add(id);
-
-        cache.removeAll(keys);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAll() {
-        cache.clear();
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java b/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java
deleted file mode 100644
index a9d4fd2..0000000
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/support/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains supporting files required by Spring Data framework.
- */
-package org.apache.ignite.springdata20.repository.support;
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
deleted file mode 100644
index ec2e7ca..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data operation with compound key when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCompoundKeyTest extends IgniteSpringDataCompoundKeyTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(CityRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Ignite ignite() {
-        return ctx.getBean("igniteServerNode", Ignite.class);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
deleted file mode 100644
index 226ee9b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-    }
-
-    /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
-    @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
-        GridTestUtils.assertThrows(log,
-            () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
-            "Query of type TextQuery is not supported by thin client. Check" +
-                " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
-                " method configuration or use Ignite node instance to connect to the Ignite cluster.");
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
deleted file mode 100644
index 27d3645..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data query operations when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataQueriesSelfTest extends IgniteSpringDataQueriesSelfTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-        repo2 = ctx.getBean(PersonSecondRepository.class);
-        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
-        for (int i = 0; i < CACHE_SIZE; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
deleted file mode 100644
index 3a65f29..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.Statement;
-import java.util.Optional;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.City;
-import org.apache.ignite.springdata.compoundkey.CityKey;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-
-/**
- * Test with using conpoud key in spring-data
- * */
-public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest {
-    /** Application context */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /** City repository */
-    protected static CityRepository repo;
-
-    /** Cache name */
-    private static final String CACHE_NAME = "City";
-
-    /** Cities count */
-    private static final int TOTAL_COUNT = 5;
-
-    /** Count Afganistan cities */
-    private static final int AFG_COUNT = 4;
-
-    /** Kabul identifier */
-    private static final int KABUL_ID = 1;
-
-    /** Quandahar identifier */
-    private static final int QUANDAHAR_ID = 2;
-
-    /** Afganistan county code */
-    private static final String AFG = "AFG";
-
-    /** test city Kabul */
-    private static final City KABUL = new City("Kabul", "Kabol", 1780000);
-
-    /** test city Quandahar */
-    private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
-
-    /**
-     * Performs context initialization before tests.
-     */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-        ctx.register(CompoundKeyApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(CityRepository.class);
-    }
-
-    /**
-     * Load data
-     * */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        loadData();
-
-        assertEquals(TOTAL_COUNT, repo.count());
-    }
-
-    /**
-     * Performs context destroy after tests.
-     */
-    @Override protected void afterTestsStopped() {
-        ctx.close();
-    }
-
-    /** load data*/
-    public void loadData() throws Exception {
-        Ignite ignite = ignite();
-
-        if (ignite.cacheNames().contains(CACHE_NAME))
-            ignite.destroyCache(CACHE_NAME);
-
-        try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:" + CLI_CONN_PORT + '/')) {
-            Statement st = conn.createStatement();
-
-            st.execute("DROP TABLE IF EXISTS City");
-            st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\"");
-            st.execute("SET STREAMING ON;");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)");
-        }
-    }
-
-    /** Test */
-    @Test
-    public void test() {
-        assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
-        assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
-        assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
-    }
-
-    /** */
-    protected Ignite ignite() {
-        return ctx.getBean(Ignite.class);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
deleted file mode 100644
index 10d016d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
-import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE;
-
-/** Tests Spring Data repository cluster connection configurations. */
-public class IgniteSpringDataConnectionConfigurationTest extends GridCommonAbstractTest {
-    /** */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
-    /** */
-    private static final String CACHE_NAME = "PersonCache";
-
-    /** */
-    private static final int CLI_CONN_PORT = 10810;
-
-    /** */
-    private static final String CLI_NAME = "cli-node";
-
-    /** */
-    private static final String SRV_NAME = "srv-node";
-
-    /** */
-    private static final String LOCAL_HOST = "127.0.0.1";
-
-    /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithIgniteConfiguration() {
-        checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
-        assertClientNodeIsStopped();
-    }
-
-    /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithClientConfiguration() {
-        checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
-    }
-
-    /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteInstanceParameter() {
-        checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteClientInstanceParameter() {
-        checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgnitClientConfigurationParameter() {
-        checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteConfigurationParameter() {
-        checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /**
-     * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
-     * used to access the Ignite cluster.
-     */
-    @Test
-    public void testRepositoryWithExistingIgniteInstance() throws Exception {
-        try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
-            checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
-            assertNotNull(Ignition.ignite(CLI_NAME));
-        }
-    }
-
-    /** Tests repository configuration in case specified cache name is invalid. */
-    @Test
-    public void testRepositoryWithInvalidCacheNameConfiguration() {
-        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
-            ctx.register(InvalidCacheNameApplication.class);
-
-            assertThrowsAnyCause(log,
-                () -> {
-                    ctx.refresh();
-
-                    return null;
-                },
-                IllegalArgumentException.class,
-                "Cache 'invalidCache' not found for repository interface" +
-                    " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
-                    " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
-                    " org.apache.ignite.springdata20.repository.config.RepositoryConfig annotation.");
-        }
-
-        assertClientNodeIsStopped();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        super.afterTest();
-
-        grid(SRV_NAME).cache(CACHE_NAME).clear();
-    }
-
-    /** */
-    private void assertClientNodeIsStopped() {
-        assertFalse(Ignition.allGrids().stream().map(Ignite::name).anyMatch(CLI_NAME::equals));
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        startGrid(getIgniteConfiguration(SRV_NAME, false));
-    }
-
-    /**
-     * Checks that repository created based on specified Spring application configuration is properly initialized and
-     * got access to the Ignite cluster.
-     */
-    private void checkRepositoryConfiguration(
-        Class<?> cfgCls,
-        Class<? extends IgniteRepository<Object, Serializable>> repoCls
-    ) {
-        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
-            ctx.register(cfgCls);
-            ctx.refresh();
-
-            IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
-
-            IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
-
-            assertEquals(0, repo.count());
-            assertEquals(0, cache.size());
-
-            int key = 0;
-
-            repo.save(key, "1");
-
-            assertEquals(1, repo.count());
-            assertNotNull(cache.get(key));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
-    public static class InvalidCacheNameApplication {
-        /** Ignite configuration bean. */
-        @Bean
-        public IgniteConfiguration igniteConfiguration() {
-            return getIgniteConfiguration(CLI_NAME, true);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
-    public static class IgniteConfigurationApplication {
-        /** Ignite configuration bean. */
-        @Bean
-        public IgniteConfiguration igniteConfiguration() {
-            return getIgniteConfiguration(CLI_NAME, true);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link ClientConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
-    public static class ClientConfigurationApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public ClientConfiguration clientConfiguration() {
-            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if Ignite bean name was not provided
-     * through {@link RepositoryConfig#igniteInstance()} ()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteBeanApplication {
-        /** Ignite bean. */
-        @Bean
-        public Ignite someIgnite() {
-            return Ignition.start(getIgniteConfiguration("test", false));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
-     * through {@link RepositoryConfig#igniteInstance()} ()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteClientBeanApplication {
-        /** Ignite client bean. */
-        @Bean
-        public IgniteClient someIgnite() {
-            return Ignition.startClient(new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
-     * through {@link RepositoryConfig#igniteCfg()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteClientConfigurationBeanApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public ClientConfiguration someCfg() {
-            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
-     * through {@link RepositoryConfig#igniteCfg()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteConfigurationBeanApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public IgniteConfiguration someCfg() {
-            return getIgniteConfiguration("test", false);
-        }
-    }
-
-    /** Repository for testing configuration approach through default ignite beans. */
-    @RepositoryConfig(cacheName = "PersonCache")
-    public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
-    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
-    public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
-    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
-    public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
-    @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
-    public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** */
-    private static IgniteConfiguration getIgniteConfiguration(String name, boolean clientMode) {
-        return new IgniteConfiguration()
-            .setIgniteInstanceName(name)
-            .setClientMode(clientMode)
-            .setLocalHost(LOCAL_HOST)
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER))
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
-            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME));
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
deleted file mode 100644
index 5841f41..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.util.Collection;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonExpressionRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * Test with using repository which is configured by Spring EL
- */
-public class IgniteSpringDataCrudSelfExpressionTest extends GridCommonAbstractTest {
-    /** Number of entries to store */
-    private static final int CACHE_SIZE = 1000;
-
-    /** Repository. */
-    private static PersonExpressionRepository repo;
-
-    /** Context. */
-    private static AnnotationConfigApplicationContext ctx;
-
-    /** */
-    @Rule
-    public final ExpectedException expected = ExpectedException.none();
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-        ctx.register(ApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonExpressionRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        fillInRepository();
-
-        assertEquals(CACHE_SIZE, repo.count());
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-
-        super.afterTest();
-    }
-
-    /** */
-    private void fillInRepository() {
-        for (int i = 0; i < CACHE_SIZE - 5; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-
-        repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() {
-        ctx.close();
-    }
-
-    /**
-     * Tests put & get operations.
-     */
-    @Test
-    public void testPutGet() {
-        Person person = new Person("some_name", "some_surname");
-
-        int id = CACHE_SIZE + 1;
-
-        assertEquals(person, repo.save(id, person));
-
-        assertTrue(repo.existsById(id));
-
-        assertEquals(person, repo.findById(id).get());
-
-        expected.expect(UnsupportedOperationException.class);
-        expected.expectMessage("Use IgniteRepository.save(key,value) method instead.");
-        repo.save(person);
-    }
-
-    /**
-     * Tests SpEL expression.
-     */
-    @Test
-    public void testCacheCount() {
-        Ignite ignite = ctx.getBean("igniteInstance", Ignite.class);
-
-        Collection<String> cacheNames = ignite.cacheNames();
-
-        assertFalse("The SpEL \"#{cacheNames.personCacheName}\" isn't processed!",
-            cacheNames.contains("#{cacheNames.personCacheName}"));
-
-        assertTrue("Cache \"PersonCache\" isn't found!",
-            cacheNames.contains("PersonCache"));
-    }
-
-    /** */
-    @Test
-    public void testCacheCountTWO() {
-        Ignite ignite = ctx.getBean("igniteInstanceTWO", Ignite.class);
-
-        Collection<String> cacheNames = ignite.cacheNames();
-
-        assertFalse("The SpEL \"#{cacheNames.personCacheName}\" isn't processed!",
-            cacheNames.contains("#{cacheNames.personCacheName}"));
-
-        assertTrue("Cache \"PersonCache\" isn't found!",
-            cacheNames.contains("PersonCache"));
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
deleted file mode 100644
index a543044..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.TreeSet;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.FullNameProjection;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * CRUD tests.
- */
-public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
-    /** Repository. */
-    protected static PersonRepository repo;
-
-    /** Context. */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /** Number of entries to store */
-    private static int CACHE_SIZE = 1000;
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(ApplicationConfiguration.class);
-
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        fillInRepository();
-
-        assertEquals(CACHE_SIZE, repo.count());
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-
-        super.afterTest();
-    }
-
-    /** */
-    private void fillInRepository() {
-        for (int i = 0; i < CACHE_SIZE - 5; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-
-        repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        ctx.destroy();
-    }
-
-    /** */
-    @Test
-    public void testPutGet() {
-        Person person = new Person("some_name", "some_surname");
-
-        int id = CACHE_SIZE + 1;
-
-        assertEquals(person, repo.save(id, person));
-
-        assertTrue(repo.existsById(id));
-
-        assertEquals(person, repo.findById(id).get());
-
-        try {
-            repo.save(person);
-
-            fail("Managed to save a Person without ID");
-        }
-        catch (UnsupportedOperationException e) {
-            //excepted
-        }
-    }
-
-    /** */
-    @Test
-    public void testPutAllGetAll() {
-        LinkedHashMap<Integer, Person> map = new LinkedHashMap<>();
-
-        for (int i = CACHE_SIZE; i < CACHE_SIZE + 50; i++)
-            map.put(i, new Person("some_name" + i, "some_surname" + i));
-
-        Iterator<Person> persons = repo.save(map).iterator();
-
-        assertEquals(CACHE_SIZE + 50, repo.count());
-
-        Iterator<Person> origPersons = map.values().iterator();
-
-        while (persons.hasNext())
-            assertEquals(origPersons.next(), persons.next());
-
-        try {
-            repo.saveAll(map.values());
-
-            fail("Managed to save a list of Persons with ids");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-
-        persons = repo.findAllById(map.keySet()).iterator();
-
-        int counter = 0;
-
-        while (persons.hasNext()) {
-            persons.next();
-            counter++;
-        }
-
-        assertEquals(map.size(), counter);
-    }
-
-    /** */
-    @Test
-    public void testGetAll() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        Iterator<Person> persons = repo.findAll().iterator();
-
-        int counter = 0;
-
-        while (persons.hasNext()) {
-            persons.next();
-            counter++;
-        }
-
-        assertEquals(repo.count(), counter);
-    }
-
-    /** */
-    @Test
-    public void testDelete() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        repo.deleteById(0);
-
-        assertEquals(CACHE_SIZE - 1, repo.count());
-        assertEquals(Optional.empty(),repo.findById(0));
-
-        try {
-            repo.delete(new Person("", ""));
-
-            fail("Managed to delete a Person without id");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-    }
-
-    /** */
-    @Test
-    public void testDeleteSet() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        TreeSet<Integer> ids = new TreeSet<>();
-
-        for (int i = 0; i < CACHE_SIZE / 2; i++)
-            ids.add(i);
-
-        repo.deleteAllById(ids);
-
-        assertEquals(CACHE_SIZE / 2, repo.count());
-
-        try {
-            ArrayList<Person> persons = new ArrayList<>();
-
-            for (int i = 0; i < 3; i++)
-                persons.add(new Person(String.valueOf(i), String.valueOf(i)));
-
-            repo.deleteAll(persons);
-
-            fail("Managed to delete Persons without ids");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-    }
-
-    /** */
-    @Test
-    public void testDeleteAll() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-    }
-
-    /**
-     * Delete existing record.
-     */
-    @Test
-    public void testDeleteByFirstName() {
-        assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
-
-        long cnt = repo.deleteByFirstName("uniquePerson");
-
-        assertEquals(1, cnt);
-    }
-
-    /**
-     * Delete NON existing record.
-     */
-    @Test
-    public void testDeleteExpression() {
-        long cnt = repo.deleteByFirstName("880");
-
-        assertEquals(0, cnt);
-    }
-
-    /**
-     * Delete Multiple records due to where.
-     */
-    @Test
-    public void testDeleteExpressionMultiple() {
-        long count = repo.countByFirstName("nonUniquePerson");
-        long cnt = repo.deleteByFirstName("nonUniquePerson");
-
-        assertEquals(cnt, count);
-    }
-
-    /**
-     * Remove should do the same than Delete.
-     */
-    @Test
-    public void testRemoveExpression() {
-        repo.removeByFirstName("person3f");
-
-        long count = repo.count();
-        assertEquals(CACHE_SIZE - 1, count);
-    }
-
-    /**
-     * Delete unique record using lower case key word.
-     */
-    @Test
-    public void testDeleteQuery() {
-        repo.deleteBySecondNameLowerCase("uniqueLastName");
-
-        long countAfter = repo.count();
-        assertEquals(CACHE_SIZE - 1, countAfter);
-    }
-
-    /**
-     * Try to delete with a wrong @Query.
-     */
-    @Test
-    public void testWrongDeleteQuery() {
-        long countBefore = repo.countByFirstNameLike("person3f");
-
-        try {
-            repo.deleteWrongByFirstNameQuery("person3f");
-        }
-        catch (Exception e) {
-            //expected
-        }
-
-        long countAfter = repo.countByFirstNameLike("person3f");
-        assertEquals(countBefore, countAfter);
-    }
-
-    /**
-     * Update with a @Query a record.
-     */
-    @Test
-    public void testUpdateQueryMixedCase() {
-        final String newSecondName = "updatedUniqueSecondName";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<Person> person = repo.findByFirstName("uniquePerson");
-        assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
-    }
-
-    /**
-     * Update with a @Query a record
-     */
-    @Test
-    public void testUpdateQueryMixedCaseProjection() {
-        final String newSecondName = "updatedUniqueSecondName1";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-
-        List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
-        assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
-        assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
-
-        FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
-        assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
-        final String newSecondName = "updatedUniqueSecondName3";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
-        final String newSecondName = "updatedUniqueSecondName4";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
-        final String newSecondName = "updatedUniqueSecondName5";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
-        final String newSecondName = "updatedUniqueSecondName6";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
-        assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
-    }
-
-    /**
-     * Update with a wrong @Query
-     */
-    @Test
-    public void testWrongUpdateQuery() {
-        final String newSecondName = "updatedUniqueSecondName";
-        int rowsUpdated = 0;
-
-        try {
-            rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
-        }
-        catch (Exception ignored) {
-            //expected
-        }
-
-        assertEquals(0, rowsUpdated);
-
-        List<Person> person = repo.findByFirstName("uniquePerson");
-        assertEquals(person.get(0).getSecondName(), "uniqueLastName");
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
deleted file mode 100644
index 0445e0d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.cache.Cache;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.Sort;
-
-/**
- *
- */
-public class IgniteSpringDataQueriesSelfTest extends GridCommonAbstractTest {
-    /** Repository. */
-    protected static PersonRepository repo;
-
-    /** Repository 2. */
-    protected static PersonSecondRepository repo2;
-
-    /**
-     * Repository Ignite Instance cluster TWO.
-     */
-    protected static PersonRepositoryOtherIgniteInstance repoTWO;
-
-    /** Context. */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /**
-     * Number of entries to store
-     */
-    protected static int CACHE_SIZE = 1000;
-
-    /**
-     * Performs context initialization before tests.
-     */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(ApplicationConfiguration.class);
-
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-        repo2 = ctx.getBean(PersonSecondRepository.class);
-        // repository on another ignite instance (and another cluster)
-        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
-        for (int i = 0; i < CACHE_SIZE; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-    }
-
-    /**
-     * Performs context destroy after tests.
-     */
-    @Override protected void afterTestsStopped() throws Exception {
-        ctx.destroy();
-    }
-
-    /** */
-    @Test
-    public void testExplicitQuery() {
-        List<Person> persons = repo.simpleQuery("person4a");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("person4a", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testExplicitQueryTWO() {
-        List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("TWOperson4a", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testEqualsPart() {
-        List<Person> persons = repo.findByFirstName("person4e");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("person4e", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testEqualsPartTWO() {
-        List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("TWOperson4e", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testContainingPart() {
-        List<Person> persons = repo.findByFirstNameContaining("person4");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertTrue(person.getFirstName().startsWith("person4"));
-    }
-
-    /** */
-    @Test
-    public void testContainingPartTWO() {
-        List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertTrue(person.getFirstName().startsWith("TWOperson4"));
-    }
-
-    /** */
-    @Test
-    public void testTopPart() {
-        Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
-
-        Iterator<Person> iter = top.iterator();
-
-        Person person = iter.next();
-
-        assertFalse(iter.hasNext());
-
-        assertTrue(person.getFirstName().startsWith("person4"));
-    }
-
-    /** */
-    @Test
-    public void testTopPartTWO() {
-        Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
-
-        Iterator<Person> iter = top.iterator();
-
-        Person person = iter.next();
-
-        assertFalse(iter.hasNext());
-
-        assertTrue(person.getFirstName().startsWith("TWOperson4"));
-    }
-
-    /** */
-    @Test
-    public void testLikeAndLimit() {
-        Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
-
-        int cnt = 0;
-
-        for (Person next : like) {
-            assertTrue(next.getFirstName().contains("person"));
-
-            cnt++;
-        }
-
-        assertEquals(10, cnt);
-    }
-
-    /** */
-    @Test
-    public void testLikeAndLimitTWO() {
-        Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
-
-        int cnt = 0;
-
-        for (Person next : like) {
-            assertTrue(next.getFirstName().contains("TWOperson"));
-
-            cnt++;
-        }
-
-        assertEquals(10, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCount() {
-        int cnt = repo.countByFirstNameLike("person");
-
-        assertEquals(1000, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCountTWO() {
-        int cnt = repoTWO.countByFirstNameLike("TWOperson");
-
-        assertEquals(1000, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCount2() {
-        int cnt = repo.countByFirstNameLike("person4");
-
-        assertTrue(cnt < 1000);
-    }
-
-    /** */
-    @Test
-    public void testCount2TWO() {
-        int cnt = repoTWO.countByFirstNameLike("TWOperson4");
-
-        assertTrue(cnt < 1000);
-    }
-
-    /** */
-    @Test
-    public void testPageable() {
-        PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, "firstName");
-
-        HashSet<String> firstNames = new HashSet<>();
-
-        List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", pageable);
-
-        assertEquals(5, pageable1.size());
-
-        for (Person person : pageable1) {
-            firstNames.add(person.getFirstName());
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-        }
-
-        List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", pageable.next());
-
-        assertEquals(5, pageable2.size());
-
-        for (Person person : pageable2) {
-            firstNames.add(person.getFirstName());
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-        }
-
-        assertEquals(10, firstNames.size());
-    }
-
-    /** */
-    @Test
-    public void testAndAndOr() {
-        int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
-
-        int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", "lastName1");
-
-        assertTrue(cntAnd <= cntOr);
-    }
-
-    /** */
-    @Test
-    public void testQueryWithSort() {
-        List<Person> persons = repo.queryWithSort("^[a-z]+$", new Sort(Sort.Direction.DESC, "secondName"));
-
-        Person previous = persons.get(0);
-
-        for (Person person : persons) {
-            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
-            previous = person;
-        }
-    }
-
-    /** */
-    @Test
-    public void testQueryWithPaging() {
-        List<Person> persons = repo.queryWithPageable("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
-
-        assertEquals(7, persons.size());
-
-        Person previous = persons.get(0);
-
-        for (Person person : persons) {
-            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
-            previous = person;
-        }
-    }
-
-    /** */
-    @Test
-    public void testQueryFields() {
-        List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
-
-        assertEquals(7, persons.size());
-    }
-
-    /** */
-    @Test
-    public void testFindCacheEntries() {
-        List<Cache.Entry<Integer, Person>> cacheEntries = repo.findBySecondNameLike("stName1");
-
-        assertFalse(cacheEntries.isEmpty());
-
-        for (Cache.Entry<Integer, Person> entry : cacheEntries)
-            assertTrue(entry.getValue().getSecondName().contains("stName1"));
-    }
-
-    /** */
-    @Test
-    public void testFindOneCacheEntry() {
-        Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
-
-        assertNotNull(cacheEntry);
-
-        assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
-    }
-
-    /** */
-    @Test
-    public void testFindOneValue() {
-        PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
-
-        assertNotNull(person);
-
-        assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
-    }
-
-    /** */
-    @Test
-    public void testSelectSeveralFields() {
-        List<List> lists = repo.selectSeveralField("^[a-z]+$", new PageRequest(2, 6));
-
-        assertEquals(6, lists.size());
-
-        for (List list : lists) {
-            assertEquals(2, list.size());
-
-            assertTrue(list.get(0) instanceof Integer);
-        }
-    }
-
-    /** */
-    @Test
-    public void testCountQuery() {
-        int cnt = repo.countQuery(".*");
-
-        assertEquals(256, cnt);
-    }
-
-    /** */
-    @Test
-    public void testSliceOfCacheEntries() {
-        Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
-
-        assertEquals(4, slice.getSize());
-
-        for (Cache.Entry<Integer, Person> entry : slice)
-            assertFalse("lastName18".equals(entry.getValue().getSecondName()));
-    }
-
-    /** */
-    @Test
-    public void testSliceOfLists() {
-        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new PageRequest(0, 3));
-
-        assertEquals(3, lists.getSize());
-
-        for (List list : lists) {
-            assertEquals(2, list.size());
-
-            assertTrue(list.get(0) instanceof Integer);
-        }
-    }
-
-    /** Tests conversion of SQL select query result to domain entity objects. */
-    @Test
-    public void testRowToEntityConversion() {
-        Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
-
-        Set<Person> exp = new HashSet<>();
-
-        repo.findAll().forEach(exp::add);
-
-        assertEquals(exp, res);
-    }
-
-    /**
-     * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
-     * of domain entity class.
-     */
-    @Test
-    public void testIncompleteRowToEntityConversion() {
-        Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
-
-        Set<Person> exp = new HashSet<>();
-
-        repo.findAll().forEach(p -> {
-            p.setSecondName(null);
-
-            exp.add(p);
-        });
-
-        assertEquals(exp, res);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
deleted file mode 100644
index e86a575..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.Objects;
-
-/**
- * Value-class
- * */
-public class City {
-    /** City name */
-    private String name;
-
-    /** City district */
-    private String district;
-
-    /** City population */
-    private int population;
-
-    /**
-     * @param name city name
-     * @param district city district
-     * @param population city population
-     * */
-    public City(String name, String district, int population) {
-        this.name = name;
-        this.district = district;
-        this.population = population;
-    }
-
-    /**
-     * @return city name
-     * */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @param name city name
-     * */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * @return city district
-     * */
-    public String getDistrict() {
-        return district;
-    }
-
-    /**
-     * @param district city district
-     * */
-    public void setDistrict(String district) {
-        this.district = district;
-    }
-
-    /**
-     * @return city population
-     * */
-    public int getPopulation() {
-        return population;
-    }
-
-    /**
-     * @param population city population
-     * */
-    public void setPopulation(int population) {
-        this.population = population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return name + " | " + district + " | " + population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        City city = (City)o;
-
-        return
-                Objects.equals(this.name, city.name) &&
-                        Objects.equals(this.district, city.district) &&
-                        this.population == city.population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(name, district, population);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
deleted file mode 100644
index 8a5dba0..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.io.Serializable;
-import java.util.Objects;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/** Compound key for city class  */
-public class CityKey implements Serializable {
-    /** city identifier */
-    private int ID;
-
-    /** affinity key countrycode  */
-    @AffinityKeyMapped
-    private String COUNTRYCODE;
-
-    /**
-     * @param id city identifier
-     * @param countryCode city countrycode
-     * */
-    public CityKey(int id, String countryCode) {
-        this.ID = id;
-        this.COUNTRYCODE = countryCode;
-    }
-
-    /**
-     * @return city id
-     * */
-    public int getId() {
-        return ID;
-    }
-
-    /**
-     * @return countrycode
-     * */
-    public String getCountryCode() {
-        return COUNTRYCODE;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        CityKey key = (CityKey)o;
-        return ID == key.ID &&
-                COUNTRYCODE.equals(key.COUNTRYCODE);
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(ID, COUNTRYCODE);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return ID + " | " + COUNTRYCODE;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
deleted file mode 100644
index d9adee3..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.stereotype.Repository;
-
-/** City repository */
-@Repository
-@RepositoryConfig(cacheName = "City", autoCreateCache = true)
-public interface CityRepository extends IgniteRepository<City, CityKey> {
-    /**
-     * Find city by id
-     * @param id city identifier
-     * @return city
-     * */
-    public City findById(int id);
-
-    /**
-     * Find all cities by coutrycode
-     * @param cc coutrycode
-     * @return list of cache enrties CityKey -> City
-     * */
-    public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
deleted file mode 100644
index 03c05cd..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Spring application configuration
- * */
-@Configuration
-@EnableIgniteRepositories
-public class CompoundKeyApplicationConfiguration {
-    /** */
-    public static final int CLI_CONN_PORT = 10810;
-
-    /**
-     * Ignite instance bean
-     * */
-    @Bean
-    public Ignite igniteInstance() {
-        return Ignition.start(new IgniteConfiguration()
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT)));
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
deleted file mode 100644
index bce3340..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.repository.query.spi.EvaluationContextExtension;
-
-/** */
-@Configuration
-@EnableIgniteRepositories
-public class ApplicationConfiguration {
-    /** */
-    public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
-
-    /** */
-    public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
-
-    /**
-     * The bean with cache names
-     */
-    @Bean
-    public CacheNamesBean cacheNames() {
-        CacheNamesBean bean = new CacheNamesBean();
-
-        bean.setPersonCacheName("PersonCache");
-
-        return bean;
-    }
-
-    /** */
-    @Bean
-    public EvaluationContextExtension sampleSpELExtension() {
-        return new SampleEvaluationContextExtension();
-    }
-
-    /** */
-    @Bean(value = "sampleExtensionBean")
-    public SamplePassParamExtension sampleExtensionBean() {
-        return new SamplePassParamExtension();
-    }
-
-    /**
-     * Ignite instance bean - no instance name provided on RepositoryConfig
-     */
-    @Bean
-    public Ignite igniteInstance() {
-        IgniteConfiguration cfg = new IgniteConfiguration();
-
-        cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
-
-        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
-        ccfg.setIndexedTypes(Integer.class, Person.class);
-
-        cfg.setCacheConfiguration(ccfg);
-
-        TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
-        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
-        cfg.setDiscoverySpi(spi);
-
-        return Ignition.start(cfg);
-    }
-
-    /**
-     * Ignite instance bean with not default name
-     */
-    @Bean
-    public Ignite igniteInstanceTWO() {
-        IgniteConfiguration cfg = new IgniteConfiguration();
-
-        cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
-
-        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
-        ccfg.setIndexedTypes(Integer.class, Person.class);
-
-        cfg.setCacheConfiguration(ccfg);
-
-        TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
-        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
-        cfg.setDiscoverySpi(spi);
-
-        return Ignition.start(cfg);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
deleted file mode 100644
index 7b69075..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata20.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.repository.query.spi.EvaluationContextExtension;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
-
-/** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
-@Configuration
-@EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
-public class IgniteClientApplicationConfiguration {
-    /** Test cache name. */
-    public static final String CACHE_NAME = "PersonCache";
-
-    /** */
-    @Bean
-    public CacheNamesBean cacheNames() {
-        CacheNamesBean bean = new CacheNamesBean();
-
-        bean.setPersonCacheName(CACHE_NAME);
-
-        return bean;
-    }
-
-    /** */
-    @Bean
-    public EvaluationContextExtension sampleSpELExtension() {
-        return new SampleEvaluationContextExtension();
-    }
-
-    /** */
-    @Bean(value = "sampleExtensionBean")
-    public SamplePassParamExtension sampleExtensionBean() {
-        return new SamplePassParamExtension();
-    }
-
-    /** */
-    @Bean
-    public Ignite igniteServerNode() {
-        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
-    }
-
-    /** */
-    @Bean
-    public Ignite igniteSecondServerNode() {
-        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
-    }
-
-    /** Ignite client instance bean with default name. */
-    @Bean
-    public IgniteClient igniteInstance() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
-            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
-    }
-
-    /** Ignite client instance bean with non-default name. */
-    @Bean
-    public IgniteClient igniteInstanceTWO() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
-    }
-
-    /**  */
-    private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
-        return new IgniteConfiguration()
-            .setIgniteInstanceName(igniteInstanceName)
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
-            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
-            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
deleted file mode 100644
index 62c3054..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Date;
-import java.util.Objects;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * DTO class.
- */
-public class Person {
-    /** First name. */
-    @QuerySqlField(index = true)
-    @QueryTextField
-    private String firstName;
-
-    /** Second name. */
-    @QuerySqlField(index = true)
-    private String secondName;
-
-    /** Birthday. */
-    @QuerySqlField
-    private Date birthday;
-
-    /**
-     * @param firstName First name.
-     * @param secondName Second name.
-     */
-    public Person(String firstName, String secondName) {
-        this.firstName = firstName;
-        this.secondName = secondName;
-        birthday = new Date();
-    }
-
-    /**
-     * @return First name.
-     */
-    public String getFirstName() {
-        return firstName;
-    }
-
-    /**
-     * @param firstName First name.
-     */
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    /**
-     * @return Second name.
-     */
-    public String getSecondName() {
-        return secondName;
-    }
-
-    /**
-     * @param secondName Second name.
-     */
-    public void setSecondName(String secondName) {
-        this.secondName = secondName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Person{" +
-            "firstName='" + firstName + '\'' +
-            ", secondName='" + secondName + '\'' +
-            ", birthday='" + birthday + '\'' +
-            '}';
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        Person person = (Person)o;
-
-        return Objects.equals(firstName, person.firstName) &&
-            Objects.equals(secondName, person.secondName) &&
-            Objects.equals(birthday, person.birthday);
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(firstName, secondName, birthday);
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
deleted file mode 100644
index 2537c57..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.io.Serializable;
-
-/**
- * Compound key.
- */
-public class PersonKey implements Serializable {
-    /** */
-    private int id1;
-
-    /** */
-    private int id2;
-
-    /**
-     * @param id1 ID1.
-     * @param id2 ID2.
-     */
-    public PersonKey(int id1, int id2) {
-        this.id1 = id1;
-        this.id2 = id2;
-    }
-
-    /**
-     * @return ID1
-     */
-    public int getId1() {
-        return id1;
-    }
-
-    /**
-     * @return ID1
-     */
-    public int getId2() {
-        return id1;
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
deleted file mode 100644
index 7ea699b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Integer> {
-    /** */
-    public List<Person> findByFirstName(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
-    /** */
-    @Query("firstName = ?#{[1]}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
-    /** */
-    @Query(textQuery = true, value = "#{#firstname}", limit = 2)
-    public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
-    @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
-    /** */
-    public List<Person> findByFirstNameContaining(String val);
-
-    /** */
-    public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
-    /** */
-    public Collection<Person> findTopByFirstNameContaining(String val);
-
-    /** */
-    public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstName(String val);
-
-    /** */
-    public int countByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
-    /** */
-    public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
-    /** */
-    public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
-    /** */
-    public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
-    /** */
-    public PersonProjection findTopBySecondNameStartingWith(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<Person> simpleQuery(String val);
-
-    /** */
-    @Query("firstName REGEXP ?")
-    public List<Person> queryWithSort(String val, Sort sort);
-
-    /** */
-    @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
-    public List<Person> queryWithPageable(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
-    public List<String> selectField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
-    public List<List> selectSeveralField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
-    public int countQuery(String val);
-
-    /** Top 3 query */
-    public List<Person> findTop3ByFirstName(String val);
-
-    /** Delete query */
-    public long deleteByFirstName(String firstName);
-
-    /** Remove Query */
-    public List<Person> removeByFirstName(String firstName);
-
-    /** Delete using @Query with keyword in lower-case */
-    @Query("delete FROM Person WHERE secondName = ?")
-    public void deleteBySecondNameLowerCase(String secondName);
-
-    /** Delete using @Query but with errors on the query */
-    @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public void deleteWrongByFirstNameQuery(String firstName);
-
-    /** Update using @Query with keyword in mixed-case */
-    @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
-    public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
-    /** Update using @Query but with errors on the query */
-    @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public int setWrongFixedSecondName(String secondName, String firstName);
-
-    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
-    @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
-    public List<Person> queryWithRowToEntityConversion();
-
-    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
-    @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
-    public List<Person> queryWithIncompleteRowToEntityConversion();
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
deleted file mode 100644
index ac6231b..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- *
- */
-@RepositoryConfig(igniteInstance = "igniteInstanceTWO", cacheName = "PersonCache")
-public interface PersonRepositoryOtherIgniteInstance extends IgniteRepository<Person, Integer> {
-    /** */
-    public List<Person> findByFirstName(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    /** */
-    @Query("firstName = ?#{[1]}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
-    /** */
-    @Query(textQuery = true, value = "#{#firstname}", limit = 2)
-    public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
-    @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
-    /** */
-    public List<Person> findByFirstNameContaining(String val);
-
-    /** */
-    public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
-    /** */
-    public Collection<Person> findTopByFirstNameContaining(String val);
-
-    /** */
-    public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstName(String val);
-
-    /** */
-    public int countByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
-    /** */
-    public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
-    /** */
-    public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
-    /** */
-    public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
-    /** */
-    public PersonProjection findTopBySecondNameStartingWith(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<Person> simpleQuery(String val);
-
-    /** */
-    @Query("firstName REGEXP ?")
-    public List<Person> queryWithSort(String val, Sort sort);
-
-    /** */
-    @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
-    public List<Person> queryWithPageable(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
-    public List<String> selectField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
-    public List<List> selectSeveralField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
-    public int countQuery(String val);
-
-    /** Top 3 query */
-    public List<Person> findTop3ByFirstName(String val);
-
-    /** Delete query */
-    public long deleteByFirstName(String firstName);
-
-    /** Remove Query */
-    public List<Person> removeByFirstName(String firstName);
-
-    /** Delete using @Query with keyword in lower-case */
-    @Query("delete FROM Person WHERE secondName = ?")
-    public void deleteBySecondNameLowerCase(String secondName);
-
-    /** Delete using @Query but with errors on the query */
-    @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public void deleteWrongByFirstNameQuery(String firstName);
-
-    /** Update using @Query with keyword in mixed-case */
-    @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
-    public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
-    /** Update using @Query but with errors on the query */
-    @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public int setWrongFixedSecondName(String secondName, String firstName);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
deleted file mode 100644
index bf77597..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
-public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
deleted file mode 100644
index 2bc713c..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.Query;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
-import org.springframework.data.domain.AbstractPageRequest;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
-    /** */
-    public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String val, PageRequest pageReq);
-
-    /** */
-    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
-    public Slice<List> querySliceOfList(String val, AbstractPageRequest pageReq);
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
deleted file mode 100644
index 0fa535d..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport;
-
-/**
- * Sample EvaluationContext Extension for Spring Data 2.0
- * <p>
- * Use SpEl expressions into your {@code @Query} definitions.
- * <p>
- * First, you need to register your extension into your spring data configuration. Sample:
- * <pre>
- * {@code @Configuration}
- * {@code @EnableIgniteRepositories}(basePackages = ... )
- * public class MyIgniteRepoConfig {
- * ...
- *      {@code @Bean}
- *      public EvaluationContextExtension sampleSpELExtension() {
- *          return new SampleEvaluationContextExtension();
- *      }
- * ...
- * }
- * </pre>
- *
- * <p>
- * Sample of usage into your {@code @Query} definitions:
- * <pre>
- * {@code @RepositoryConfig}(cacheName = "users")
- * public interface UserRepository
- * extends IgniteRepository<User, UUID>{
- *     [...]
- *
- *     {@code @Query}(value = "SELECT * from #{#entityName} where email = ?#{sampleExtension.transformParam(#email)}")
- *     User searchUserByEmail(@Param("email") String email);
- *
- *      [...]
- *     }
- * </pre>
- * <p>
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public class SampleEvaluationContextExtension extends EvaluationContextExtensionSupport {
-    /** */
-    private static final SamplePassParamExtension SAMPLE_PASS_PARAM_EXTENSION_INSTANCE = new SamplePassParamExtension();
-
-    /** */
-    private static final Map<String, Object> properties = new HashMap<>();
-
-    /** */
-    private static final String SAMPLE_EXTENSION_SPEL_VAR = "sampleExtension";
-
-    static {
-        properties.put(SAMPLE_EXTENSION_SPEL_VAR, SAMPLE_PASS_PARAM_EXTENSION_INSTANCE);
-    }
-
-    /** */
-    @Override public String getExtensionId() {
-        return "HK-SAMPLE-PASS-PARAM-EXTENSION";
-    }
-
-    /** */
-    @Override public Map<String, Object> getProperties() {
-        return properties;
-    }
-
-    /** */
-    public static class SamplePassParamExtension {
-        // just return same param
-        public Object transformParam(Object param) {
-            return param;
-        }
-    }
-}
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java b/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java
deleted file mode 100644
index 88879e2..0000000
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData2TestSuite.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.testsuites;
-
-import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Ignite Spring Data 2.0 test suite.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    IgniteSpringDataCrudSelfTest.class,
-    IgniteSpringDataQueriesSelfTest.class,
-    IgniteSpringDataCrudSelfExpressionTest.class,
-    IgniteSpringDataCompoundKeyTest.class,
-    IgniteSpringDataConnectionConfigurationTest.class,
-    IgniteClientSpringDataCrudSelfTest.class,
-    IgniteClientSpringDataQueriesSelfTest.class,
-    IgniteClientSpringDataCompoundKeyTest.class
-})
-public class IgniteSpringData2TestSuite {
-}
diff --git a/modules/spring-data-2.2-ext/README.txt b/modules/spring-data-2.2-ext/README.txt
deleted file mode 100644
index f069dc0..0000000
--- a/modules/spring-data-2.2-ext/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Apache Ignite Spring Module
----------------------------
-
-Apache Ignite Spring Data 2.2 extension provides an integration with Spring Data 2.2 framework.
-
-Main features:
-
-- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
-- Supports query tuning parameters in @Query annotation
-- Supports projections
-- Supports Page and Stream responses
-- Supports Sql Fields Query resultset transformation into the domain entity
-- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
-- Supports advanced parameter binding and SpEL expressions into SQL queries:
-- Template variables:
-    - #entityName - the simple class name of the domain entity
-- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
-- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
-- Supports SpEL expressions into Text queries (TextQuery).
-
-Importing Spring Data 2.2 extension In Maven Project
-----------------------------------------
-
-If you are using Maven to manage dependencies of your project, you can add Spring Data 2.2 extension
-dependency like this (replace '${ignite-spring-data-2.2-ext.version}' with actual version of Ignite Spring Data 2.2
-extension you are interested in):
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
-                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    ...
-    <dependencies>
-        ...
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.2-ext</artifactId>
-            <version>${ignite-spring-data-2.2-ext.version}</version>
-        </dependency>
-        ...
-    </dependencies>
-    ...
-</project>
diff --git a/modules/spring-data-2.2-ext/examples/config/example-default.xml b/modules/spring-data-2.2-ext/examples/config/example-default.xml
deleted file mode 100644
index e6c359d..0000000
--- a/modules/spring-data-2.2-ext/examples/config/example-default.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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.
--->
-
-<!--
-    Ignite configuration with all defaults and enabled p2p deployment and enabled events.
--->
-<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 abstract="true" id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
-        <!-- Set to true to enable distributed class loading for examples, default is false. -->
-        <property name="peerClassLoadingEnabled" value="true"/>
-
-        <!-- Enable task execution events for examples. -->
-        <property name="includeEventTypes">
-            <list>
-                <!--Task execution events-->
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED"/>
-
-                <!--Cache events-->
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ"/>
-                <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED"/>
-            </list>
-        </property>
-
-        <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
-        <property name="discoverySpi">
-            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
-                <property name="ipFinder">
-                    <!--
-                        Ignite provides several options for automatic discovery that can be used
-                        instead os static IP based discovery. For information on all options refer
-                        to our documentation: http://apacheignite.readme.io/docs/cluster-config
-                    -->
-                    <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
-                    <!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
-                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
-                        <property name="addresses">
-                            <list>
-                                <!-- In distributed environment, replace with actual host IP address. -->
-                                <value>127.0.0.1:47500..47509</value>
-                            </list>
-                        </property>
-                    </bean>
-                </property>
-            </bean>
-        </property>
-    </bean>
-</beans>
diff --git a/modules/spring-data-2.2-ext/examples/pom.xml b/modules/spring-data-2.2-ext/examples/pom.xml
deleted file mode 100644
index 04a69b1..0000000
--- a/modules/spring-data-2.2-ext/examples/pom.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?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.
--->
-
-<!--
-    POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.ignite</groupId>
-        <artifactId>ignite-extensions-parent</artifactId>
-        <version>1</version>
-        <relativePath>../../../parent</relativePath>
-    </parent>
-
-    <artifactId>ignite-spring-data-2.2-ext-examples</artifactId>
-    <version>${ignite-spring-data-2.2-ext.version}</version>
-    <url>http://ignite.apache.org</url>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.2-ext</artifactId>
-            <version>${ignite-spring-data-2.2-ext.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-indexing</artifactId>
-            <version>${ignite.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-tx</artifactId>
-            <version>${spring-5.2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring-5.2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring</artifactId>
-            <version>${ignite.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-context</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
deleted file mode 100644
index 2127eaf..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/EmployeeKey.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/**
- * This class represents key for employee object.
- * <p>
- * Used in query example to collocate employees
- * with their organizations.
- */
-public class EmployeeKey {
-    /** ID. */
-    private int id;
-
-    /** Organization ID. */
-    @AffinityKeyMapped
-    private int organizationId;
-
-    /**
-     * Required for binary deserialization.
-     */
-    public EmployeeKey() {
-        // No-op.
-    }
-
-    /**
-     * @param id ID.
-     * @param organizationId Organization ID.
-     */
-    public EmployeeKey(int id, int organizationId) {
-        this.id = id;
-        this.organizationId = organizationId;
-    }
-
-    /**
-     * @return ID.
-     */
-    public int id() {
-        return id;
-    }
-
-    /**
-     * @return Organization ID.
-     */
-    public int organizationId() {
-        return organizationId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        EmployeeKey key = (EmployeeKey)o;
-
-        return id == key.id && organizationId == key.organizationId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = id;
-
-        res = 31 * res + organizationId;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "EmployeeKey [id=" + id +
-            ", organizationId=" + organizationId + ']';
-    }
-}
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
deleted file mode 100644
index a6ba676..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Organization.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import java.sql.Timestamp;
-import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-
-/**
- * This class represents organization object.
- */
-public class Organization {
-    /** */
-    private static final AtomicLong ID_GEN = new AtomicLong();
-
-    /** Organization ID (indexed). */
-    @QuerySqlField(index = true)
-    private Long id;
-
-    /** Organization name (indexed). */
-    @QuerySqlField(index = true)
-    private String name;
-
-    /** Address. */
-    private Address addr;
-
-    /** Type. */
-    private OrganizationType type;
-
-    /** Last update time. */
-    private Timestamp lastUpdated;
-
-    /**
-     * Required for binary deserialization.
-     */
-    public Organization() {
-        // No-op.
-    }
-
-    /**
-     * @param name Organization name.
-     */
-    public Organization(String name) {
-        id = ID_GEN.incrementAndGet();
-
-        this.name = name;
-    }
-
-    /**
-     * @param id Organization ID.
-     * @param name Organization name.
-     */
-    public Organization(long id, String name) {
-        this.id = id;
-        this.name = name;
-    }
-
-    /**
-     * @param name Name.
-     * @param addr Address.
-     * @param type Type.
-     * @param lastUpdated Last update time.
-     */
-    public Organization(String name, Address addr, OrganizationType type, Timestamp lastUpdated) {
-        id = ID_GEN.incrementAndGet();
-
-        this.name = name;
-        this.addr = addr;
-        this.type = type;
-
-        this.lastUpdated = lastUpdated;
-    }
-
-    /**
-     * @return Organization ID.
-     */
-    public Long id() {
-        return id;
-    }
-
-    /**
-     * @return Name.
-     */
-    public String name() {
-        return name;
-    }
-
-    /**
-     * @return Address.
-     */
-    public Address address() {
-        return addr;
-    }
-
-    /**
-     * @return Type.
-     */
-    public OrganizationType type() {
-        return type;
-    }
-
-    /**
-     * @return Last update time.
-     */
-    public Timestamp lastUpdated() {
-        return lastUpdated;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Organization [id=" + id +
-            ", name=" + name +
-            ", address=" + addr +
-            ", type=" + type +
-            ", lastUpdated=" + lastUpdated + ']';
-    }
-}
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java b/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java
deleted file mode 100644
index 585c458..0000000
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Person.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.examples.model;
-
-import java.io.Serializable;
-import java.util.concurrent.atomic.AtomicLong;
-import org.apache.ignite.cache.affinity.AffinityKey;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * Person class.
- */
-public class Person implements Serializable {
-    /** */
-    private static final AtomicLong ID_GEN = new AtomicLong();
-
-    /** Person ID (indexed). */
-    @QuerySqlField(index = true)
-    public Long id;
-
-    /** Organization ID (indexed). */
-    @QuerySqlField(index = true)
-    public Long orgId;
-
-    /** First name (not-indexed). */
-    @QuerySqlField
-    public String firstName;
-
-    /** Last name (not indexed). */
-    @QuerySqlField
-    public String lastName;
-
-    /** Resume text (create LUCENE-based TEXT index for this field). */
-    @QueryTextField
-    public String resume;
-
-    /** Salary (indexed). */
-    @QuerySqlField(index = true)
-    public double salary;
-
-    /** Custom cache key to guarantee that person is always collocated with its organization. */
-    private transient AffinityKey<Long> key;
-
-    /**
-     * Default constructor.
-     */
-    public Person() {
-        // No-op.
-    }
-
-    /**
-     * Constructs person record.
-     *
-     * @param org       Organization.
-     * @param firstName First name.
-     * @param lastName  Last name.
-     * @param salary    Salary.
-     * @param resume    Resume text.
-     */
-    public Person(Organization org, String firstName, String lastName, double salary, String resume) {
-        // Generate unique ID for this person.
-        id = ID_GEN.incrementAndGet();
-
-        orgId = org.id();
-
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.salary = salary;
-        this.resume = resume;
-    }
-
-    /**
-     * Constructs person record.
-     *
-     * @param id Person ID.
-     * @param orgId Organization ID.
-     * @param firstName First name.
-     * @param lastName Last name.
-     * @param salary    Salary.
-     * @param resume    Resume text.
-     */
-    public Person(Long id, Long orgId, String firstName, String lastName, double salary, String resume) {
-        this.id = id;
-        this.orgId = orgId;
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.salary = salary;
-        this.resume = resume;
-    }
-
-    /**
-     * Constructs person record.
-     *
-     * @param id Person ID.
-     * @param firstName First name.
-     * @param lastName Last name.
-     */
-    public Person(Long id, String firstName, String lastName) {
-        this.id = id;
-
-        this.firstName = firstName;
-        this.lastName = lastName;
-    }
-
-    /**
-     * Gets cache affinity key. Since in some examples person needs to be collocated with organization, we create
-     * custom affinity key to guarantee this collocation.
-     *
-     * @return Custom affinity key to guarantee that person is always collocated with organization.
-     */
-    public AffinityKey<Long> key() {
-        if (key == null)
-            key = new AffinityKey<>(id, orgId);
-
-        return key;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override public String toString() {
-        return "Person [id=" + id +
-                ", orgId=" + orgId +
-                ", lastName=" + lastName +
-                ", firstName=" + firstName +
-                ", salary=" + salary +
-                ", resume=" + resume + ']';
-    }
-}
diff --git a/modules/spring-data-2.2-ext/licenses/apache-2.0.txt b/modules/spring-data-2.2-ext/licenses/apache-2.0.txt
deleted file mode 100644
index d645695..0000000
--- a/modules/spring-data-2.2-ext/licenses/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
diff --git a/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml b/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml
deleted file mode 100755
index 3061bd4..0000000
--- a/modules/spring-data-2.2-ext/modules/core/src/test/config/log4j-test.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?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.
--->
-
-<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
-    "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
-<!--
-    Log4j configuration.
--->
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
-    <!--
-        Logs System.out messages to console.
-    -->
-    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
-        <!-- Log to STDOUT. -->
-        <param name="Target" value="System.out"/>
-
-        <!-- Log from DEBUG and higher. -->
-        <param name="Threshold" value="DEBUG"/>
-
-        <!-- The default pattern: Date Priority [Category] Message\n -->
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-
-        <!-- Do not log beyond INFO level. -->
-        <filter class="org.apache.log4j.varia.LevelRangeFilter">
-            <param name="levelMin" value="DEBUG"/>
-            <param name="levelMax" value="INFO"/>
-        </filter>
-    </appender>
-
-    <!--
-        Logs all System.err messages to console.
-    -->
-    <appender name="CONSOLE_ERR" class="org.apache.log4j.ConsoleAppender">
-        <!-- Log to STDERR. -->
-        <param name="Target" value="System.err"/>
-
-        <!-- Log from WARN and higher. -->
-        <param name="Threshold" value="WARN"/>
-
-        <!-- The default pattern: Date Priority [Category] Message\n -->
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-    </appender>
-
-    <!--
-        Logs all output to specified file.
-    -->
-    <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
-        <param name="Threshold" value="DEBUG"/>
-        <param name="File" value="ignite/work/log/ignite.log"/>
-        <param name="Append" value="true"/>
-        <param name="MaxFileSize" value="10MB"/>
-        <param name="MaxBackupIndex" value="10"/>
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
-        </layout>
-    </appender>
-
-    <!-- Disable all open source debugging. -->
-    <category name="org">
-        <level value="INFO"/>
-    </category>
-
-    <category name="org.eclipse.jetty">
-        <level value="INFO"/>
-    </category>
-
-    <!-- Default settings. -->
-    <root>
-        <!-- Print at info by default. -->
-        <level value="INFO"/>
-
-        <!-- Append to file and console. -->
-        <appender-ref ref="FILE"/>
-        <appender-ref ref="CONSOLE"/>
-        <appender-ref ref="CONSOLE_ERR"/>
-    </root>
-</log4j:configuration>
diff --git a/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties b/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties
deleted file mode 100644
index 0faf5b8..0000000
--- a/modules/spring-data-2.2-ext/modules/core/src/test/config/tests.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Local address to bind to.
-local.ip=127.0.0.1
-
-# TCP communication port
-comm.tcp.port=30010
diff --git a/modules/spring-data-2.2-ext/pom.xml b/modules/spring-data-2.2-ext/pom.xml
deleted file mode 100644
index 3db1ee1..0000000
--- a/modules/spring-data-2.2-ext/pom.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?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.
--->
-
-<!--
-    POM file.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.ignite</groupId>
-        <artifactId>ignite-extensions-parent</artifactId>
-        <version>1</version>
-        <relativePath>../../parent</relativePath>
-    </parent>
-
-    <artifactId>ignite-spring-data-2.2-ext</artifactId>
-    <version>${ignite-spring-data-2.2-ext.version}</version>
-    <url>http://ignite.apache.org</url>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-indexing</artifactId>
-            <version>${ignite.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-commons</artifactId>
-            <version>${ignite-spring-data-commons.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring-5.2.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-tx</artifactId>
-            <version>${spring-5.2.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.2.version}</version>
-            <scope>provided</scope>
-            <!-- Exclude slf4j logging in favor of log4j -->
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>jcl-over-slf4j</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>${commons.lang.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-log4j</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-context</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-tools</artifactId>
-            <version>${ignite.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java
deleted file mode 100644
index 9a4e793..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/IgniteRepository.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository;
-
-import java.io.Serializable;
-import java.util.Map;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.repository.CrudRepository;
-
-/**
- * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
-    /**
-     * Returns the Ignite instance bound to the repository
-     *
-     * @return the Ignite instance bound to the repository
-     */
-    public Ignite ignite();
-
-    /**
-     * Returns the Ignite Cache bound to the repository
-     *
-     * @return the Ignite Cache bound to the repository
-     */
-    public IgniteCache<K, V> cache();
-
-    /**
-     * Saves a given entity using provided key.
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>    Entity type.
-     * @param key    Entity's key.
-     * @param entity Entity to save.
-     * @return Saved entity.
-     */
-    public <S extends V> S save(K key, S entity);
-
-    /**
-     * Saves all given keys and entities combinations.
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>      Type of entities.
-     * @param entities Map of key-entities pairs to save.
-     * @return Saved entities.
-     */
-    public <S extends V> Iterable<S> save(Map<K, S> entities);
-
-    /**
-     * Saves a given entity using provided key with expiry policy
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>       Entity type.
-     * @param key       Entity's key.
-     * @param entity    Entity to save.
-     * @param expiryPlc ExpiryPolicy to apply, if not null.
-     * @return Saved entity.
-     */
-    public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
-
-    /**
-     * Saves all given keys and entities combinations with expiry policy
-     * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
-     * (keys) that are not unique cluster wide.
-     *
-     * @param <S>       Type of entities.
-     * @param entities  Map of key-entities pairs to save.
-     * @param expiryPlc ExpiryPolicy to apply, if not null.
-     * @return Saved entities.
-     */
-    public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
-
-    /**
-     * Deletes all the entities for the provided ids.
-     *
-     * @param ids List of ids to delete.
-     */
-    public void deleteAllById(Iterable<? extends K> ids);
-
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java
deleted file mode 100644
index 560ee2e..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/EnableIgniteRepositories.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryImpl;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Import;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-
-/**
- * Annotation to activate Apache Ignite repositories. If no base package is configured through either {@link #value()},
- * {@link #basePackages()} or {@link #basePackageClasses()} it will trigger scanning of the package of annotated class.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-@Import(IgniteRepositoriesRegistar.class)
-public @interface EnableIgniteRepositories {
-    /**
-     * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
-     * {@code @EnableIgniteRepositories("org.my.pkg")} instead of
-     * {@code @EnableIgniteRepositories(basePackages="org.my.pkg")}.
-     */
-    String[] value() default {};
-
-    /**
-     * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with)
-     * this attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
-     */
-    String[] basePackages() default {};
-
-    /**
-     * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components.
-     * The package of each class specified will be scanned. Consider creating a special no-op marker class or interface
-     * in each package that serves no purpose other than being referenced by this attribute.
-     */
-    Class<?>[] basePackageClasses() default {};
-
-    /**
-     * Specifies which types are not eligible for component scanning.
-     */
-    Filter[] excludeFilters() default {};
-
-    /**
-     * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
-     * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or
-     * filters.
-     */
-    Filter[] includeFilters() default {};
-
-    /**
-     * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
-     * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
-     * for {@code PersonRepositoryImpl}.
-     *
-     * @return Postfix to be used when looking up custom repository implementations.
-     */
-    String repositoryImplementationPostfix() default "Impl";
-
-    /**
-     * Configures the location of where to find the Spring Data named queries properties file.
-     *
-     * @return Location of where to find the Spring Data named queries properties file.
-     */
-    String namedQueriesLocation() default "";
-
-    /**
-     * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
-     * {@link Key#CREATE_IF_NOT_FOUND}.
-     *
-     * @return Key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods.
-     */
-    Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
-
-    /**
-     * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
-     * IgniteRepositoryFactoryBean}.
-     *
-     * @return {@link FactoryBean} class to be used for each repository instance.
-     */
-    Class<?> repositoryFactoryBeanClass() default IgniteRepositoryFactoryBean.class;
-
-    /**
-     * Configure the repository base class to be used to create repository proxies for this particular configuration.
-     *
-     * @return Repository base class to be used to create repository proxies for this particular configuration.
-     */
-    Class<?> repositoryBaseClass() default IgniteRepositoryImpl.class;
-
-    /**
-     * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
-     * repositories infrastructure.
-     */
-    boolean considerNestedRepositories() default false;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java
deleted file mode 100644
index ddecd77..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoriesRegistar.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Annotation;
-
-import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryBeanDefinitionRegistrarSupport}.
- */
-public class IgniteRepositoriesRegistar extends RepositoryBeanDefinitionRegistrarSupport {
-    /** {@inheritDoc} */
-    @Override protected Class<? extends Annotation> getAnnotation() {
-        return EnableIgniteRepositories.class;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected RepositoryConfigurationExtension getExtension() {
-        return new IgniteRepositoryConfigurationExtension();
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java
deleted file mode 100644
index cf6db05..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/IgniteRepositoryConfigurationExtension.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.util.Collection;
-import java.util.Collections;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.support.IgniteProxyFactory;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.data.repository.config.RepositoryConfigurationExtension;
-import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
-import org.springframework.data.repository.config.RepositoryConfigurationSource;
-
-import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
-
-/**
- * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
- */
-public class IgniteRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
-    /** Name of the auto-registered Ignite proxy factory bean. */
-    private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
-
-    /** Name of the auto-registered Ignite proxy bean prototype. */
-    private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
-
-    /** {@inheritDoc} */
-    @Override public String getModuleName() {
-        return "Apache Ignite";
-    }
-
-    /** {@inheritDoc} */
-    @Override protected String getModulePrefix() {
-        return "ignite";
-    }
-
-    /** {@inheritDoc} */
-    @Override public String getRepositoryFactoryBeanClassName() {
-        return IgniteRepositoryFactoryBean.class.getName();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Collection<Class<?>> getIdentifyingTypes() {
-        return Collections.singleton(IgniteRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
-        registerIfNotAlreadyRegistered(
-            () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
-            registry,
-            IGNITE_PROXY_FACTORY_BEAN_NAME,
-            cfg);
-
-        registerIfNotAlreadyRegistered(
-            () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
-                .setScope(SCOPE_PROTOTYPE)
-                .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
-                .getBeanDefinition(),
-            registry,
-            IGNITE_PROXY_BEAN_NAME,
-            cfg);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java
deleted file mode 100644
index 1ea4bf3..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/Query.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-
-/**
- * Annotation to provide a user defined query for a method.
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface Query {
-    /**
-     * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
-     * (only if textQuery = false (default))
-     */
-    String value() default "";
-
-    /**
-     * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
-     * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
-     *
-     * @see RepositoryConfig#igniteInstance()
-     */
-    boolean textQuery() default false;
-
-    /**
-     * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
-     * statements or to not return hidden fields on SELECT * statements.
-     */
-    boolean forceFieldsQuery() default false;
-
-    /**
-     * Sets flag defining if this query is collocated.
-     * <p>
-     * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
-     * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
-     * of your query selection are collocated together on the same node and you group by collocated key (primary or
-     * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
-     * nodes.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean collocated() default false;
-
-    /**
-     * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
-     * timeout is exceeded. Zero value disables timeout
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    int timeout() default 0;
-
-    /**
-     * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
-     * tables in join. By default is {@code false}.
-     * <p>
-     * It is not recommended to enable this property until you are sure that your indexes and the query itself are
-     * correct and tuned as much as possible but query optimizer still produces wrong join order.
-     *
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean enforceJoinOrder() default false;
-
-    /**
-     * Specify if distributed joins are enabled for this query.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    boolean distributedJoins() default false;
-
-    /**
-     * Sets lazy query execution flag.
-     * <p>
-     * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
-     * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
-     * increasing concurrency.
-     * <p>
-     * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
-     * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
-     * consumption at the cost of moderate performance hit.
-     * <p>
-     * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
-     * <p>
-     * Only applicable to SqlFieldsQuery
-     */
-    boolean lazy() default false;
-
-    /**
-     * Sets whether this query should be executed on local node only.
-     */
-    boolean local() default false;
-
-    /**
-     * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
-     * partitions.
-     * <p>
-     * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
-     * <p>
-     * Only applicable to SqlFieldsQuery and SqlQuery
-     */
-    int[] parts() default {};
-
-    /**
-     * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
-     * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
-     * <p>
-     * Please, note that  {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
-     * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
-     */
-    boolean dynamicQuery() default false;
-
-    /**
-     * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
-     */
-    int limit() default 0;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java
deleted file mode 100644
index e890052..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/RepositoryConfig.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.config;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-
-/**
- * The annotation can be used to pass Ignite specific parameters to a bound repository.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-public @interface RepositoryConfig {
-    /**
-     * Cache name string.
-     *
-     * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
-     */
-    String cacheName() default "";
-
-    /**
-     * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
-     * Ignite cluster.
-     */
-    String igniteInstance() default "igniteInstance";
-
-    /**
-     * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
-     * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
-     */
-    String igniteCfg() default "igniteCfg";
-
-    /**
-     * Ignite spring cfg path string. Default "igniteSpringCfgPath".
-     *
-     * @return A path to Ignite's Spring XML configuration spring bean name
-     */
-    String igniteSpringCfgPath() default "igniteSpringCfgPath";
-
-    /**
-     * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
-     * <p>
-     * Tells to Ignite Repository factory wether cache should be auto created if not exists.
-     *
-     * @return the boolean
-     */
-    boolean autoCreateCache() default false;
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java
deleted file mode 100644
index 4e3203b..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes Spring Data integration related configuration files.
- */
-package org.apache.ignite.springdata22.repository.config;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java
deleted file mode 100644
index 2a865f5..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains Apache Ignite Spring Data integration.
- */
-package org.apache.ignite.springdata22.repository;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java
deleted file mode 100644
index dad35e2..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/DeclaredQuery.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.util.List;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.util.StringUtils;
-
-/**
- * A wrapper for a String representation of a query offering information about the query.
- *
- * @author Jens Schauder
- */
-interface DeclaredQuery {
-    /**
-     * Creates a {@literal DeclaredQuery} from a query {@literal String}.
-     *
-     * @param qry might be {@literal null} or empty.
-     * @return a {@literal DeclaredQuery} instance even for a {@literal null} or empty argument.
-     */
-    public static DeclaredQuery of(@Nullable String qry) {
-        return StringUtils.isEmpty(qry) ? EmptyDeclaredQuery.EMPTY_QUERY : new StringQuery(qry);
-    }
-
-    /**
-     * @return whether the underlying query has at least one named parameter.
-     */
-    public boolean hasNamedParameter();
-
-    /**
-     * Returns the query string.
-     */
-    public String getQueryString();
-
-    /**
-     * Returns the main alias used in the query.
-     *
-     * @return the alias
-     */
-    @Nullable
-    public String getAlias();
-
-    /**
-     * Returns whether the query is using a constructor expression.
-     */
-    public boolean hasConstructorExpression();
-
-    /**
-     * Returns whether the query uses the default projection, i.e. returns the main alias defined for the query.
-     */
-    public boolean isDefaultProjection();
-
-    /**
-     * Returns the {@link StringQuery.ParameterBinding}s registered.
-     */
-    public List<StringQuery.ParameterBinding> getParameterBindings();
-
-    /**
-     * Creates a new {@literal DeclaredQuery} representing a count query, i.e. a query returning the number of rows to
-     * be expected from the original query, either derived from the query wrapped by this instance or from the
-     * information passed as arguments.
-     *
-     * @param cntQry           an optional query string to be used if present.
-     * @param cntQryProjection an optional return type for the query.
-     * @return a new {@literal DeclaredQuery} instance.
-     */
-    public DeclaredQuery deriveCountQuery(@Nullable String cntQry, @Nullable String cntQryProjection);
-
-    /**
-     * @return whether paging is implemented in the query itself, e.g. using SpEL expressions.
-     */
-    public default boolean usesPaging() {
-        return false;
-    }
-
-    /**
-     * Returns whether the query uses JDBC style parameters, i.e. parameters denoted by a simple ? without any index or
-     * name.
-     *
-     * @return Whether the query uses JDBC style parameters.
-     */
-    public boolean usesJdbcStyleParameters();
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java
deleted file mode 100644
index b045a4f..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQuery.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import org.apache.ignite.internal.util.typedef.internal.S;
-
-/**
- * Ignite query helper class. For internal use only.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteQuery {
-    /** */
-    enum Option {
-        /** Query will be used with Sort object. */
-        SORTING,
-
-        /** Query will be used with Pageable object. */
-        PAGINATION,
-
-        /** No advanced option. */
-        NONE
-    }
-
-    /**
-     * Query text string.
-     */
-    private final String qrySql;
-
-    /**
-     * Whether this is a SQL fields query
-     */
-    private final boolean isFieldQuery;
-
-    /**
-     * Whether this is Text query
-     */
-    private final boolean isTextQuery;
-
-    /**
-     * Whether was autogenerated (by method name)
-     */
-    private final boolean isAutogenerated;
-
-    /**
-     * Type of option.
-     */
-    private final Option option;
-
-    /**
-     * @param qrySql          the query string.
-     * @param isFieldQuery    Is field query.
-     * @param isTextQuery     Is a TextQuery
-     * @param isAutogenerated query was autogenerated
-     * @param option          Option.
-     */
-    public IgniteQuery(String qrySql,
-        boolean isFieldQuery,
-        boolean isTextQuery,
-        boolean isAutogenerated,
-        Option option) {
-        this.qrySql = qrySql;
-        this.isFieldQuery = isFieldQuery;
-        this.isTextQuery = isTextQuery;
-        this.isAutogenerated = isAutogenerated;
-        this.option = option;
-    }
-
-    /**
-     * Text string of the query.
-     *
-     * @return SQL query text string.
-     */
-    public String qryStr() {
-        return qrySql;
-    }
-
-    /**
-     * Returns {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
-     *
-     * @return {@code true} if it's Ignite SQL fields query, {@code false} otherwise.
-     */
-    public boolean isFieldQuery() {
-        return isFieldQuery;
-    }
-
-    /**
-     * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
-     *
-     * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
-     */
-    public boolean isTextQuery() {
-        return isTextQuery;
-    }
-
-    /**
-     * Returns {@code true} if it's autogenerated, {@code false} otherwise.
-     *
-     * @return {@code true} if it's autogenerated, {@code false} otherwise.
-     */
-    public boolean isAutogenerated() {
-        return isAutogenerated;
-    }
-
-    /**
-     * Advanced querying option.
-     *
-     * @return querying option.
-     */
-    public Option options() {
-        return option;
-    }
-
-    /** */
-    @Override public String toString() {
-        return S.toString(IgniteQuery.class, this);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java
deleted file mode 100644
index a0be11d..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteQueryGenerator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.lang.reflect.Method;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.mapping.PropertyPath;
-import org.springframework.data.mapping.PropertyReferenceException;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.parser.Part;
-import org.springframework.data.repository.query.parser.PartTree;
-
-/**
- * Ignite query generator for Spring Data framework.
- */
-public class IgniteQueryGenerator {
-    /** */
-    private IgniteQueryGenerator() {
-        // No-op.
-    }
-
-    /**
-     * @param mtd      Method.
-     * @param metadata Metadata.
-     * @return Generated ignite query.
-     */
-    public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
-        PartTree parts;
-
-        try {
-            parts = new PartTree(mtd.getName(), metadata.getDomainType());
-        }
-        catch (PropertyReferenceException e) {
-            parts = new PartTree(mtd.getName(), metadata.getIdType());
-        }
-
-        boolean isCountOrFieldQuery = parts.isCountProjection();
-
-        StringBuilder sql = new StringBuilder();
-
-        if (parts.isDelete()) {
-            sql.append("DELETE ");
-
-            // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
-            isCountOrFieldQuery = true;
-        }
-        else {
-            sql.append("SELECT ");
-
-            if (parts.isDistinct())
-                throw new UnsupportedOperationException("DISTINCT clause in not supported.");
-
-            if (isCountOrFieldQuery)
-                sql.append("COUNT(1) ");
-            else
-                sql.append("* ");
-        }
-
-        sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
-
-        if (parts.iterator().hasNext()) {
-            sql.append(" WHERE ");
-
-            for (PartTree.OrPart orPart : parts) {
-                sql.append("(");
-
-                for (Part part : orPart) {
-                    handleQueryPart(sql, part, metadata.getDomainType());
-                    sql.append(" AND ");
-                }
-
-                sql.delete(sql.length() - 5, sql.length());
-
-                sql.append(") OR ");
-            }
-
-            sql.delete(sql.length() - 4, sql.length());
-        }
-
-        addSorting(sql, parts.getSort());
-
-        if (parts.isLimiting()) {
-            sql.append(" LIMIT ");
-            sql.append(parts.getMaxResults().intValue());
-        }
-
-        return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
-    }
-
-    /**
-     * Add a dynamic part of query for the sorting support.
-     *
-     * @param sql  SQL text string.
-     * @param sort Sort method.
-     * @return Sorting criteria in StringBuilder.
-     */
-    public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
-        if (sort != null && sort != Sort.unsorted()) {
-            sql.append(" ORDER BY ");
-
-            for (Sort.Order order : sort) {
-                sql.append(order.getProperty()).append(" ").append(order.getDirection());
-
-                if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
-                    sql.append(" ").append("NULL ");
-
-                    switch (order.getNullHandling()) {
-                        case NULLS_FIRST:
-                            sql.append("FIRST");
-                            break;
-                        case NULLS_LAST:
-                            sql.append("LAST");
-                            break;
-                        default:
-                    }
-                }
-                sql.append(", ");
-            }
-
-            sql.delete(sql.length() - 2, sql.length());
-        }
-
-        return sql;
-    }
-
-    /**
-     * Add a dynamic part of a query for the pagination support.
-     *
-     * @param sql      Builder instance.
-     * @param pageable Pageable instance.
-     * @return Builder instance.
-     */
-    public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
-
-        addSorting(sql, pageable.getSort());
-
-        sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
-
-        return sql;
-    }
-
-    /**
-     * Determines whether query is dynamic or not (by list of method parameters)
-     *
-     * @param mtd Method.
-     * @return type of options
-     */
-    public static IgniteQuery.Option getOptions(Method mtd) {
-        IgniteQuery.Option option = IgniteQuery.Option.NONE;
-
-        Class<?>[] types = mtd.getParameterTypes();
-        if (types.length > 0) {
-            Class<?> type = types[types.length - 1];
-
-            if (Sort.class.isAssignableFrom(type))
-                option = IgniteQuery.Option.SORTING;
-            else if (Pageable.class.isAssignableFrom(type))
-                option = IgniteQuery.Option.PAGINATION;
-        }
-
-        for (int i = 0; i < types.length - 1; i++) {
-            Class<?> tp = types[i];
-
-            if (tp == Sort.class || tp == Pageable.class)
-                throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
-        }
-
-        return option;
-    }
-
-    /**
-     * Check and correct table name if using column name from compound key.
-     */
-    private static String getColumnName(Part part, Class<?> domainType) {
-        PropertyPath prperty = part.getProperty();
-
-        if (prperty.getType() != domainType)
-            return domainType.getSimpleName() + "." + prperty.getSegment();
-        else
-            return part.toString();
-    }
-
-    /**
-     * Transform part to qryStr expression
-     */
-    private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
-        sql.append("(");
-
-        sql.append(getColumnName(part, domainType));
-
-        switch (part.getType()) {
-            case SIMPLE_PROPERTY:
-                sql.append("=?");
-                break;
-            case NEGATING_SIMPLE_PROPERTY:
-                sql.append("<>?");
-                break;
-            case GREATER_THAN:
-                sql.append(">?");
-                break;
-            case GREATER_THAN_EQUAL:
-                sql.append(">=?");
-                break;
-            case LESS_THAN:
-                sql.append("<?");
-                break;
-            case LESS_THAN_EQUAL:
-                sql.append("<=?");
-                break;
-            case IS_NOT_NULL:
-                sql.append(" IS NOT NULL");
-                break;
-            case IS_NULL:
-                sql.append(" IS NULL");
-                break;
-            case BETWEEN:
-                sql.append(" BETWEEN ? AND ?");
-                break;
-            case FALSE:
-                sql.append(" = FALSE");
-                break;
-            case TRUE:
-                sql.append(" = TRUE");
-                break;
-            //TODO: review this legacy code, LIKE should be -> LIKE ?
-            case LIKE:
-            case CONTAINING:
-                sql.append(" LIKE '%' || ? || '%'");
-                break;
-            case NOT_CONTAINING:
-                //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
-            case NOT_LIKE:
-                sql.append(" NOT LIKE '%' || ? || '%'");
-                break;
-            case STARTING_WITH:
-                sql.append(" LIKE  ? || '%'");
-                break;
-            case ENDING_WITH:
-                sql.append(" LIKE '%' || ?");
-                break;
-            case IN:
-                sql.append(" IN ?");
-                break;
-            case NOT_IN:
-                sql.append(" NOT IN ?");
-                break;
-            case REGEX:
-                sql.append(" REGEXP ?");
-                break;
-            case NEAR:
-            case AFTER:
-            case BEFORE:
-            case EXISTS:
-            default:
-                throw new UnsupportedOperationException(part.getType() + " is not supported!");
-        }
-
-        sql.append(")");
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
deleted file mode 100644
index 26b8fb9..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/IgniteRepositoryQuery.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.cache.Cache;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.reflect.FieldUtils;
-import org.apache.ignite.IgniteException;
-import org.apache.ignite.cache.query.FieldsQueryCursor;
-import org.apache.ignite.cache.query.Query;
-import org.apache.ignite.cache.query.QueryCursor;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.cache.query.SqlQuery;
-import org.apache.ignite.cache.query.TextQuery;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.springdata22.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata22.repository.query.StringQuery.ParameterBinding;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.SliceImpl;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.projection.ProjectionFactory;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.query.Parameter;
-import org.springframework.data.repository.query.Parameters;
-import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.ParserContext;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.util.StringUtils;
-
-import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
-import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
-import static org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactory.isFieldQuery;
-
-/**
- * Ignite query implementation.
- * <p>
- * <p>
- * Features:
- * <ol>
- * <li> Supports query tuning parameters</li>
- * <li> Supports projections</li>
- * <li> Supports Page and Stream responses</li>
- * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
- * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
- * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
- * <ol>
- * <li><b>Template variables</b>:
- * <ol>
- * <li>{@code #entityName} - the simple class name of the domain entity</li>
- * </ol>
- * </li>
- * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
- * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
- * ?#{[0]} or ?#{#myParamName}</li>
- * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
- * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
- * through SpEL EvaluationContext extension model.</li>
- * </ol>
- * Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
- * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
- * Pageable pageable);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
- * User searchUserByEmail(String email);
- *
- * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
- * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
- * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
- * <pre>
- * {@code @Query}(textQuery = true, value = "email: #{#email}")
- * User searchUserByEmail({@code @Param}("email") String email);
- *
- * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
- * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{[0]}")
- * List<User> searchUsersByText(String textToSearch, Pageable pageable);
- *
- * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
- * .match('city', #city)).build()}")
- * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
- * </pre>
- * </li>
- * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
- * <pre>
- * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
- * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
- *
- * {@code @Query}(dynamicQuery = true)
- * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
- * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
- *
- * ...
- * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
- * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
- *
- * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
- * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
- *
- * </pre>
- * </li>
- * </ol>
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@SuppressWarnings("unchecked")
-public class IgniteRepositoryQuery implements RepositoryQuery {
-    /**
-     * Defines the way how to process query result
-     */
-    private enum ReturnStrategy {
-        /** Need to return only one value. */
-        ONE_VALUE,
-
-        /** Need to return one cache entry */
-        CACHE_ENTRY,
-
-        /** Need to return list of cache entries */
-        LIST_OF_CACHE_ENTRIES,
-
-        /** Need to return list of values */
-        LIST_OF_VALUES,
-
-        /** Need to return list of lists */
-        LIST_OF_LISTS,
-
-        /** Need to return slice */
-        SLICE_OF_VALUES,
-
-        /** Slice of cache entries */
-        SLICE_OF_CACHE_ENTRIES,
-
-        /** Slice of lists */
-        SLICE_OF_LISTS,
-
-        /** Need to return Page of values */
-        PAGE_OF_VALUES,
-
-        /** Need to return stream of values */
-        STREAM_OF_VALUES,
-    }
-
-    /** */
-    private final Class<?> type;
-
-    /** Domain entitiy field descriptors mapped to their names in lower case. */
-    private final Map<String, Field> domainEntitiyFields;
-
-    /** */
-    private final IgniteQuery staticQuery;
-
-    /** */
-    private final IgniteCacheProxy<?, ?> cache;
-
-    /** */
-    private final Method mtd;
-
-    /** */
-    private final RepositoryMetadata metadata;
-
-    /** */
-    private final ProjectionFactory factory;
-
-    /** */
-    private final ReturnStrategy staticReturnStgy;
-
-    /** Detect if returned data from method is projected */
-    private final boolean hasProjection;
-
-    /** Whether projection is dynamic (provided as method parameter) */
-    private final boolean hasDynamicProjection;
-
-    /** Dynamic projection parameter index */
-    private final int dynamicProjectionIndex;
-
-    /** Dynamic query configuration */
-    private final int dynamicQueryConfigurationIndex;
-
-    /** The return query method */
-    private final QueryMethod qMethod;
-
-    /** The return domain class of QueryMethod */
-    private final Class<?> returnedDomainClass;
-
-    /** */
-    private final SpelExpressionParser expressionParser;
-
-    /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
-    private final QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider;
-
-    /** Static query configuration. */
-    private final DynamicQueryConfig staticQueryConfiguration;
-
-    /**
-     * Instantiates a new Ignite repository query.
-     *
-     * @param metadata                             Metadata.
-     * @param staticQuery                          Query.
-     * @param mtd                                  Method.
-     * @param factory                              Factory.
-     * @param cache                                Cache.
-     * @param staticQueryConfiguration             the query configuration
-     * @param queryMethodEvaluationContextProvider the query method evaluation context provider
-     */
-    public IgniteRepositoryQuery(
-        RepositoryMetadata metadata,
-        @Nullable IgniteQuery staticQuery,
-        Method mtd,
-        ProjectionFactory factory,
-        IgniteCacheProxy<? ,?> cache,
-        @Nullable DynamicQueryConfig staticQueryConfiguration,
-        QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider) {
-        this.metadata = metadata;
-        this.mtd = mtd;
-        this.factory = factory;
-        type = metadata.getDomainType();
-
-        domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
-            .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
-
-        this.cache = cache;
-
-        this.staticQueryConfiguration = staticQueryConfiguration;
-        this.staticQuery = staticQuery;
-
-        if (this.staticQuery != null)
-            staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
-        else
-            staticReturnStgy = null;
-
-        expressionParser = new SpelExpressionParser();
-        this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
-
-        qMethod = getQueryMethod();
-
-        // control projection
-        hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
-        hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
-            .isProjecting();
-
-        dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
-
-        returnedDomainClass = getQueryMethod().getReturnedObjectType();
-
-        dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
-
-        // ensure dynamic query configuration param exists if dynamicQuery = true
-        if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
-            throw new IllegalStateException(
-                "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
-                    + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
-        }
-    }
-
-    /**
-     * {@inheritDoc} @param values the values
-     *
-     * @return the object
-     */
-    @Override public Object execute(Object[] values) {
-        Object[] parameters = values;
-
-        // config via Query annotation (dynamicQuery = false)
-        DynamicQueryConfig config = staticQueryConfiguration;
-
-        // or condition to allow query tunning
-        if (config == null || dynamicQueryConfigurationIndex != -1) {
-            DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
-            parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
-            if (newConfig != null) {
-                // upset query configuration
-                config = newConfig;
-            }
-        }
-        // query configuration is required, via Query annotation or per parameter (within provided values param)
-        if (config == null) {
-            throw new IllegalStateException(
-                "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
-                    + ".repository.config.Query annotation, you must provide a non null method parameter of type "
-                    + "DynamicQueryConfig");
-        }
-
-        IgniteQuery qry = getQuery(config);
-
-        ReturnStrategy returnStgy = getReturnStgy(qry);
-
-        Query iQry = prepareQuery(qry, config, returnStgy, parameters);
-
-        QueryCursor qryCursor;
-
-        try {
-            qryCursor = cache.query(iQry);
-        }
-        catch (IllegalArgumentException e) {
-            if (cache instanceof IgniteClientCacheProxy) {
-                throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
-                    " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
-                    iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
-            }
-
-            throw e;
-        }
-
-        return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
-    }
-
-    /** {@inheritDoc} */
-    @Override public QueryMethod getQueryMethod() {
-        return new QueryMethod(mtd, metadata, factory);
-    }
-
-    private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
-        Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
-        int i = 0;
-        boolean found = false;
-        int index = -1;
-        while (it.hasNext()) {
-            T parameter = it.next();
-
-            if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
-                if (found) {
-                    throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
-                        + "Only ONE DynamicQueryConfig parameter is allowed");
-                }
-
-                found = true;
-                index = i;
-            }
-
-            i++;
-        }
-        return index;
-    }
-
-    /**
-     * @param mtd Method.
-     * @param isFieldQry Is field query.
-     * @return Return strategy type.
-     */
-    private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
-        Class<?> returnType = mtd.getReturnType();
-
-        if (returnType == Slice.class) {
-            if (isFieldQry) {
-                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
-                    return ReturnStrategy.SLICE_OF_LISTS;
-            }
-            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
-                return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
-            return ReturnStrategy.SLICE_OF_VALUES;
-        }
-        else if (returnType == Page.class)
-            return ReturnStrategy.PAGE_OF_VALUES;
-        else if (returnType == Stream.class)
-            return ReturnStrategy.STREAM_OF_VALUES;
-        else if (Cache.Entry.class.isAssignableFrom(returnType))
-            return ReturnStrategy.CACHE_ENTRY;
-        else if (Iterable.class.isAssignableFrom(returnType)) {
-            if (isFieldQry) {
-                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
-                    return ReturnStrategy.LIST_OF_LISTS;
-            }
-            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
-                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
-            return ReturnStrategy.LIST_OF_VALUES;
-        }
-        else
-            return ReturnStrategy.ONE_VALUE;
-    }
-
-    /**
-     * @param cls Class.
-     * @param mtd Method.
-     * @return if {@code mtd} return type is assignable from {@code cls}
-     */
-    private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
-        Type genericReturnType = mtd.getGenericReturnType();
-
-        if (!(genericReturnType instanceof ParameterizedType))
-            return false;
-
-        Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
-
-        if (actualTypeArguments.length == 0)
-            return false;
-
-        if (actualTypeArguments[0] instanceof ParameterizedType) {
-            ParameterizedType type = (ParameterizedType)actualTypeArguments[0];
-
-            Class<?> type1 = (Class)type.getRawType();
-
-            return type1.isAssignableFrom(cls);
-        }
-
-        if (actualTypeArguments[0] instanceof Class) {
-            Class typeArg = (Class)actualTypeArguments[0];
-
-            return typeArg.isAssignableFrom(cls);
-        }
-
-        return false;
-    }
-
-    /**
-     * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
-     *
-     * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
-     * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
-     */
-    private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
-        if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
-            return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
-
-        return (T)object;
-    }
-
-    /**
-     * @param cfg Config.
-     */
-    private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
-        if (staticQuery != null)
-            return staticQuery;
-
-        if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
-            return new IgniteQuery(cfg.value(),
-                !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
-                false, IgniteQueryGenerator.getOptions(mtd));
-        }
-
-        throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
-            + ".apache.ignite.springdata.repository.config.Query annotation, you must"
-            + " provide a non null method parameter of type DynamicQueryConfig with a "
-            + "non empty value (query string) or textQuery = true");
-    }
-
-    /**
-     * @param qry Query.
-     */
-    private ReturnStrategy getReturnStgy(IgniteQuery qry) {
-        if (staticReturnStgy != null)
-            return staticReturnStgy;
-
-        if (qry != null)
-            return calcReturnType(mtd, qry.isFieldQuery());
-
-        throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
-            + "via org.apache.ignite.springdata.repository.config.Query annotation, "
-            + "you must provide a non null method parameter of type "
-            + "DynamicQueryConfig with a non empty value (query string) or textQuery "
-            + "= true");
-    }
-
-    /**
-     * @param cls Class.
-     */
-    private static boolean isPrimitiveOrWrapper(Class<?> cls) {
-        return cls.isPrimitive() ||
-            Boolean.class.equals(cls) ||
-            Byte.class.equals(cls) ||
-            Character.class.equals(cls) ||
-            Short.class.equals(cls) ||
-            Integer.class.equals(cls) ||
-            Long.class.equals(cls) ||
-            Float.class.equals(cls) ||
-            Double.class.equals(cls) ||
-            Void.class.equals(cls) ||
-            String.class.equals(cls) ||
-            UUID.class.equals(cls);
-    }
-
-    /**
-     * @param prmtrs    Prmtrs.
-     * @param qryCursor Query cursor.
-     * @return Query cursor or slice
-     */
-    @Nullable
-    private Object transformQueryCursor(IgniteQuery qry,
-        ReturnStrategy returnStgy,
-        Object[] prmtrs,
-        QueryCursor qryCursor) {
-        final Class<?> returnClass;
-
-        if (hasProjection) {
-            if (hasDynamicProjection)
-                returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
-            else
-                returnClass = returnedDomainClass;
-        }
-        else
-            returnClass = returnedDomainClass;
-
-        if (qry.isFieldQuery()) {
-            // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
-            boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
-
-            FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
-
-            Function<List<?>, ?> cWrapperTransformFunction = null;
-
-            if (type.equals(returnClass))
-                cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
-            else {
-                if (hasProjection || singlePrimitiveResult) {
-                    if (singlePrimitiveResult)
-                        cWrapperTransformFunction = row -> row.get(0);
-                    else {
-                        // Map row -> projection class
-                        cWrapperTransformFunction = row -> factory
-                            .createProjection(returnClass, rowToMap(row, fieldQryCur));
-                    }
-                }
-                else
-                    cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
-            }
-
-            QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
-                cWrapperTransformFunction);
-
-            switch (returnStgy) {
-                case PAGE_OF_VALUES:
-                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
-                case LIST_OF_VALUES:
-                    return cWrapper.getAll();
-                case STREAM_OF_VALUES:
-                    return cWrapper.stream();
-                case ONE_VALUE:
-                    Iterator<?> iter = cWrapper.iterator();
-                    if (iter.hasNext()) {
-                        Object resp = iter.next();
-                        U.closeQuiet(cWrapper);
-                        return resp;
-                    }
-                    return null;
-                case SLICE_OF_VALUES:
-                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case SLICE_OF_LISTS:
-                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case LIST_OF_LISTS:
-                    return qryCursor.getAll();
-                default:
-                    throw new IllegalStateException();
-            }
-        }
-        else {
-            Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
-
-            if (hasProjection && !type.equals(returnClass))
-                cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
-            else
-                cWrapperTransformFunction = Cache.Entry::getValue;
-
-            QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
-                (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
-
-            switch (returnStgy) {
-                case PAGE_OF_VALUES:
-                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
-                case LIST_OF_VALUES:
-                    return cWrapper.getAll();
-                case STREAM_OF_VALUES:
-                    return cWrapper.stream();
-                case ONE_VALUE:
-                    Iterator<?> iter1 = cWrapper.iterator();
-                    if (iter1.hasNext()) {
-                        Object resp = iter1.next();
-                        U.closeQuiet(cWrapper);
-                        return resp;
-                    }
-                    return null;
-                case CACHE_ENTRY:
-                    Iterator<?> iter2 = qryCursor.iterator();
-                    if (iter2.hasNext()) {
-                        Object resp2 = iter2.next();
-                        U.closeQuiet(qryCursor);
-                        return resp2;
-                    }
-                    return null;
-                case SLICE_OF_VALUES:
-                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case SLICE_OF_CACHE_ENTRIES:
-                    return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-                case LIST_OF_CACHE_ENTRIES:
-                    return qryCursor.getAll();
-                default:
-                    throw new IllegalStateException();
-            }
-        }
-    }
-
-    /**
-     * Extract bindable values
-     *
-     * @param values            values invoking query method
-     * @param queryMethodParams query method parameter definitions
-     * @param queryBindings     All parameters found on query string that need to be binded
-     * @return new list of parameters
-     */
-    private Object[] extractBindableValues(Object[] values,
-        Parameters<?, ?> queryMethodParams,
-        List<ParameterBinding> queryBindings) {
-        // no binding params then exit
-        if (queryBindings.isEmpty())
-            return values;
-
-        Object[] newValues = new Object[queryBindings.size()];
-
-        // map bindable parameters from query method: (index/name) - index
-        HashMap<String, Integer> methodParams = new HashMap<>();
-
-        // create an evaluation context for custom query
-        EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
-            .getEvaluationContext(queryMethodParams, values);
-
-        // By default queryEvalContext:
-        // - make accesible query method parameters by index:
-        // @Query("select u from User u where u.age = ?#{[0]}")
-        // List<User> findUsersByAge(int age);
-        // - make accesible query method parameters by name:
-        // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
-        // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
-
-        // query method param's index by name and position
-        queryMethodParams.getBindableParameters().forEach(p -> {
-            if (p.isNamedParameter()) {
-                // map by name (annotated by @Param)
-                methodParams.put(p.getName().get(), p.getIndex());
-            }
-            // map by position
-            methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
-        });
-
-        // process all parameters on query and extract new values to bind
-        for (int i = 0; i < queryBindings.size(); i++) {
-            ParameterBinding p = queryBindings.get(i);
-
-            if (p.isExpression()) {
-                // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
-                newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
-            }
-            else {
-                // Extract parameter value by name or position respectively from invoking values
-                newValues[i] = values[methodParams.get(
-                    p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
-            }
-        }
-
-        return newValues;
-    }
-
-    /**
-     * @param qry        Query.
-     * @param config     Config.
-     * @param returnStgy Return stgy.
-     * @param values     Values.
-     * @return prepared query for execution
-     */
-    private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
-        Object[] parameters = values;
-
-        String queryString = qry.qryStr();
-
-        Query query;
-
-        checkRequiredPageable(returnStgy, values);
-
-        if (!qry.isTextQuery()) {
-            if (!qry.isAutogenerated()) {
-                StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
-                queryString = squery.getQueryString();
-                parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
-                    squery.getParameterBindings());
-            }
-            else {
-                // remove dynamic projection from parameters
-                if (hasDynamicProjection)
-                    parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
-            }
-
-            switch (qry.options()) {
-                case SORTING:
-                    queryString = IgniteQueryGenerator
-                        .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
-                        .toString();
-                    if (qry.isAutogenerated())
-                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
-                    break;
-                case PAGINATION:
-                    queryString = IgniteQueryGenerator
-                        .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
-                        .toString();
-                    if (qry.isAutogenerated())
-                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
-                    break;
-                default:
-            }
-
-            if (qry.isFieldQuery()) {
-                SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
-                sqlFieldsQry.setArgs(parameters);
-
-                sqlFieldsQry.setCollocated(config.collocated());
-                sqlFieldsQry.setDistributedJoins(config.distributedJoins());
-                sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
-                sqlFieldsQry.setLazy(config.lazy());
-                sqlFieldsQry.setLocal(config.local());
-
-                if (config.parts() != null && config.parts().length > 0)
-                    sqlFieldsQry.setPartitions(config.parts());
-
-                sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
-                query = sqlFieldsQry;
-            }
-            else {
-                SqlQuery sqlQry = new SqlQuery(type, queryString);
-                sqlQry.setArgs(parameters);
-
-                sqlQry.setDistributedJoins(config.distributedJoins());
-                sqlQry.setLocal(config.local());
-
-                if (config.parts() != null && config.parts().length > 0)
-                    sqlQry.setPartitions(config.parts());
-
-                sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
-
-                query = sqlQry;
-            }
-        }
-        else {
-            int pageSize = -1;
-
-            switch (qry.options()) {
-                case PAGINATION:
-                    pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
-                    break;
-            }
-
-            // check if queryString contains SpEL template expressions and evaluate them if any
-            if (queryString.contains("#{")) {
-                EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
-                    .getEvaluationContext(getQueryMethod().getParameters(),
-                        values);
-
-                Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
-                    .getValue(queryEvalContext);
-
-                if (!(eval instanceof String)) {
-                    throw new IllegalStateException(
-                        "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
-                            .getName()
-                            + ". Please, check your expression: " + queryString);
-                }
-                queryString = (String)eval;
-            }
-
-            TextQuery textQuery = new TextQuery(type, queryString, config.limit());
-
-            textQuery.setLocal(config.local());
-
-            if (pageSize > -1)
-                textQuery.setPageSize(pageSize);
-
-            query = textQuery;
-        }
-        return query;
-    }
-
-    /**
-     * @param row SQL result row.
-     * @param cursor SQL query result cursor through which {@param row} was obtained.
-     * @return SQL result row values mapped to corresponding column names.
-     */
-    private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
-        // use treemap with case insensitive property name
-        final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-
-        for (int i = 0; i < row.size(); i++) {
-            // don't want key or val columns
-            final String fieldName = cursor.getFieldName(i).toLowerCase();
-
-            if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
-                map.put(fieldName, row.get(i));
-        }
-
-        return map;
-    }
-
-    /**
-     * convert row ( with list of field values) into domain entity
-     *
-     * @param row SQL query result row.
-     * @param cursor SQL query result cursor through which {@param row} was obtained.
-     * @return Entitiy instance.
-     */
-    private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
-        Constructor<?> ctor;
-
-        try {
-            ctor = type.getDeclaredConstructor();
-
-            ctor.setAccessible(true);
-        }
-        catch (NoSuchMethodException | SecurityException ignored) {
-            ctor = null;
-        }
-
-        try {
-            Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
-
-            for (int i = 0; i < row.size(); i++) {
-                Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
-
-                if (entityField != null)
-                    FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
-            }
-
-            return (V)res;
-        }
-        catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
-            throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
-        }
-    }
-
-    /**
-     * Validates operations that requires Pageable parameter
-     *
-     * @param returnStgy Return stgy.
-     * @param prmtrs     Prmtrs.
-     */
-    private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
-        try {
-            if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
-                || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
-                Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
-                page.isPaged();
-            }
-        }
-        catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
-            throw new IllegalStateException(
-                "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
-        }
-    }
-
-    /**
-     * Ignite QueryCursor wrapper.
-     * <p>
-     * Ensures closing underline cursor when there is no data.
-     *
-     * @param <T> input type
-     * @param <V> transformed output type
-     */
-    public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
-        /**
-         * Delegate query cursor.
-         */
-        private final QueryCursor<T> delegate;
-
-        /**
-         * Transformer.
-         */
-        private final Function<T, V> transformer;
-
-        /**
-         * Instantiates a new Query cursor wrapper.
-         *
-         * @param delegate    delegate QueryCursor with T input elements
-         * @param transformer Function to transform T to V elements
-         */
-        public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
-            this.delegate = delegate;
-            this.transformer = transformer;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Iterator<V> iterator() {
-            final Iterator<T> it = delegate.iterator();
-
-            return new Iterator<V>() {
-                /** */
-                @Override public boolean hasNext() {
-                    if (!it.hasNext()) {
-                        U.closeQuiet(delegate);
-                        return false;
-                    }
-                    return true;
-                }
-
-                /** */
-                @Override public V next() {
-                    final V r = transformer.apply(it.next());
-                    if (r != null)
-                        return r;
-                    throw new NoSuchElementException();
-                }
-            };
-        }
-
-        /** {@inheritDoc} */
-        @Override public void close() {
-            U.closeQuiet(delegate);
-        }
-
-        /** {@inheritDoc} */
-        @Override public List<V> getAll() {
-            final List<V> data = new ArrayList<>();
-            delegate.forEach(i -> data.add(transformer.apply(i)));
-            U.closeQuiet(delegate);
-            return data;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int size() {
-            return 0;
-        }
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java
deleted file mode 100644
index 90cc292..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/QueryUtils.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.query;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.data.util.Streamable;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-import static java.util.regex.Pattern.DOTALL;
-import static java.util.regex.Pattern.compile;
-
-/**
- * Simple utility class to create queries.
- *
- * @author Oliver Gierke
- * @author Kevin Raymond
- * @author Thomas Darimont
- * @author Komi Innocent
- * @author Christoph Strobl
- * @author Mark Paluch
- * @author Sébastien Péralta
- * @author Jens Schauder
- * @author Nils Borrmann
- * @author Reda.Housni -Alaoui
- */
-public abstract class QueryUtils {
-    /**
-     * The constant COUNT_QUERY_STRING.
-     */
-    public static final String COUNT_QUERY_STRING = "select count(%s) from %s x";
-
-    /**
-     * The constant DELETE_ALL_QUERY_STRING.
-     */
-    public static final String DELETE_ALL_QUERY_STRING = "delete from %s x";
-
-    /**
-     * Used Regex/Unicode categories (see http://www.unicode.org/reports/tr18/#General_Category_Property): Z Separator
-     * Cc Control Cf Format P Punctuation
-     */
-    private static final String IDENTIFIER = "[._[\\P{Z}&&\\P{Cc}&&\\P{Cf}&&\\P{P}]]+";
-
-    /**
-     * The Colon no double colon.
-     */
-    static final String COLON_NO_DOUBLE_COLON = "(?<![:\\\\]):";
-
-    /**
-     * The Identifier group.
-     */
-    static final String IDENTIFIER_GROUP = String.format("(%s)", IDENTIFIER);
-
-    /** */
-    private static final String COUNT_REPLACEMENT_TEMPLATE = "select count(%s) $5$6$7";
-
-    /** */
-    private static final String SIMPLE_COUNT_VALUE = "$2";
-
-    /** */
-    private static final String COMPLEX_COUNT_VALUE = "$3$6";
-
-    /** */
-    private static final String ORDER_BY_PART = "(?iu)\\s+order\\s+by\\s+.*$";
-
-    /** */
-    private static final Pattern ALIAS_MATCH;
-
-    /** */
-    private static final Pattern COUNT_MATCH;
-
-    /** */
-    private static final Pattern PROJECTION_CLAUSE = Pattern
-        .compile("select\\s+(.+)\\s+from", Pattern.CASE_INSENSITIVE);
-
-    /** */
-    private static final String JOIN = "join\\s+(fetch\\s+)?" + IDENTIFIER + "\\s+(as\\s+)?" + IDENTIFIER_GROUP;
-
-    /** */
-    private static final Pattern JOIN_PATTERN = Pattern.compile(JOIN, Pattern.CASE_INSENSITIVE);
-
-    /** */
-    private static final String EQUALS_CONDITION_STRING = "%s.%s = :%s";
-
-    /** */
-    private static final Pattern NAMED_PARAMETER = Pattern.compile(
-        COLON_NO_DOUBLE_COLON + IDENTIFIER + "|\\#" + IDENTIFIER, CASE_INSENSITIVE);
-
-    /** */
-    private static final Pattern CONSTRUCTOR_EXPRESSION;
-
-    /** */
-    private static final int QUERY_JOIN_ALIAS_GROUP_INDEX = 3;
-
-    /** */
-    private static final int VARIABLE_NAME_GROUP_INDEX = 4;
-
-    /** */
-    private static final Pattern FUNCTION_PATTERN;
-
-    static {
-        StringBuilder builder = new StringBuilder();
-        builder.append("(?<=from)"); // from as starting delimiter
-        builder.append("(?:\\s)+"); // at least one space separating
-        builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any
-        builder.append("(?:\\sas)*"); // exclude possible "as" keyword
-        builder.append("(?:\\s)+"); // at least one space separating
-        builder.append("(?!(?:where))(\\w+)"); // the actual alias
-
-        ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE);
-
-        builder = new StringBuilder();
-        builder.append("(select\\s+((distinct )?(.+?)?)\\s+)?(from\\s+");
-        builder.append(IDENTIFIER);
-        builder.append("(?:\\s+as)?\\s+)");
-        builder.append(IDENTIFIER_GROUP);
-        builder.append("(.*)");
-
-        COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE);
-
-        builder = new StringBuilder();
-        builder.append("select");
-        builder.append("\\s+"); // at least one space separating
-        builder.append("(.*\\s+)?"); // anything in between (e.g. distinct) at least one space separating
-        builder.append("new");
-        builder.append("\\s+"); // at least one space separating
-        builder.append(IDENTIFIER);
-        builder.append("\\s*"); // zero to unlimited space separating
-        builder.append("\\(");
-        builder.append(".*");
-        builder.append("\\)");
-
-        CONSTRUCTOR_EXPRESSION = compile(builder.toString(), CASE_INSENSITIVE + DOTALL);
-
-        builder = new StringBuilder();
-        // any function call including parameters within the brackets
-        builder.append("\\w+\\s*\\([\\w\\.,\\s'=]+\\)");
-        // the potential alias
-        builder.append("\\s+[as|AS]+\\s+(([\\w\\.]+))");
-
-        FUNCTION_PATTERN = compile(builder.toString());
-    }
-
-    /**
-     * Private constructor to prevent instantiation.
-     */
-    private QueryUtils() {
-        // No-op.
-    }
-
-    /**
-     * Returns the query string to execute an exists query for the given id attributes.
-     *
-     * @param entityName        the name of the entity to create the query for, must not be {@literal null}.
-     * @param cntQryPlaceHolder the placeholder for the count clause, must not be {@literal null}.
-     * @param idAttrs           the id attributes for the entity, must not be {@literal null}.
-     * @return the exists query string
-     */
-    public static String getExistsQueryString(String entityName,
-        String cntQryPlaceHolder,
-        Iterable<String> idAttrs) {
-        String whereClause = Streamable.of(idAttrs).stream() //
-            .map(idAttribute -> String.format(EQUALS_CONDITION_STRING, "x", idAttribute,
-                idAttribute)) //
-            .collect(Collectors.joining(" AND ", " WHERE ", ""));
-
-        return String.format(COUNT_QUERY_STRING, cntQryPlaceHolder, entityName) + whereClause;
-    }
-
-    /**
-     * Returns the query string for the given class name.
-     *
-     * @param template   must not be {@literal null}.
-     * @param entityName must not be {@literal null}.
-     * @return the template with placeholders replaced by the {@literal entityName}. Guaranteed to be not {@literal
-     *     null}.
-     */
-    public static String getQueryString(String template, String entityName) {
-        Assert.hasText(entityName, "Entity name must not be null or empty!");
-
-        return String.format(template, entityName);
-    }
-
-    /**
-     * Returns the aliases used for {@code left (outer) join}s.
-     *
-     * @param qry a query string to extract the aliases of joins from. Must not be {@literal null}.
-     * @return a {@literal Set} of aliases used in the query. Guaranteed to be not {@literal null}.
-     */
-    static Set<String> getOuterJoinAliases(String qry) {
-        Set<String> result = new HashSet<>();
-        Matcher matcher = JOIN_PATTERN.matcher(qry);
-
-        while (matcher.find()) {
-            String alias = matcher.group(QUERY_JOIN_ALIAS_GROUP_INDEX);
-            if (StringUtils.hasText(alias))
-                result.add(alias);
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the aliases used for aggregate functions like {@code SUM, COUNT, ...}.
-     *
-     * @param qry a {@literal String} containing a query. Must not be {@literal null}.
-     * @return a {@literal Set} containing all found aliases. Guaranteed to be not {@literal null}.
-     */
-    static Set<String> getFunctionAliases(String qry) {
-        Set<String> result = new HashSet<>();
-        Matcher matcher = FUNCTION_PATTERN.matcher(qry);
-
-        while (matcher.find()) {
-            String alias = matcher.group(1);
-
-            if (StringUtils.hasText(alias))
-                result.add(alias);
-        }
-
-        return result;
-    }
-
-    /**
-     * Resolves the alias for the entity to be retrieved from the given JPA query.
-     *
-     * @param qry must not be {@literal null}.
-     * @return Might return {@literal null}.
-     */
-    @Nullable
-    static String detectAlias(String qry) {
-        Matcher matcher = ALIAS_MATCH.matcher(qry);
-
-        return matcher.find() ? matcher.group(2) : null;
-    }
-
-    /**
-     * Creates a count projected query from the given original query.
-     *
-     * @param originalQry   must not be {@literal null}.
-     * @param cntProjection may be {@literal null}.
-     * @return a query String to be used a count query for pagination. Guaranteed to be not {@literal null}.
-     */
-    static String createCountQueryFor(String originalQry, @Nullable String cntProjection) {
-        Assert.hasText(originalQry, "OriginalQuery must not be null or empty!");
-
-        Matcher matcher = COUNT_MATCH.matcher(originalQry);
-        String countQuery;
-
-        if (cntProjection == null) {
-            String variable = matcher.matches() ? matcher.group(VARIABLE_NAME_GROUP_INDEX) : null;
-            boolean useVariable = variable != null && StringUtils.hasText(variable) && !variable.startsWith("new")
-                && !variable.startsWith("count(") && !variable.contains(",");
-
-            String replacement = useVariable ? SIMPLE_COUNT_VALUE : COMPLEX_COUNT_VALUE;
-            countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, replacement));
-        }
-        else
-            countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, cntProjection));
-
-        return countQuery.replaceFirst(ORDER_BY_PART, "");
-    }
-
-    /**
-     * Returns whether the given JPQL query contains a constructor expression.
-     *
-     * @param qry must not be {@literal null} or empty.
-     * @return boolean
-     */
-    public static boolean hasConstructorExpression(String qry) {
-        Assert.hasText(qry, "Query must not be null or empty!");
-
-        return CONSTRUCTOR_EXPRESSION.matcher(qry).find();
-    }
-
-    /**
-     * Returns the projection part of the query, i.e. everything between {@code select} and {@code from}.
-     *
-     * @param qry must not be {@literal null} or empty.
-     * @return projection
-     */
-    public static String getProjection(String qry) {
-        Assert.hasText(qry, "Query must not be null or empty!");
-
-        Matcher matcher = PROJECTION_CLAUSE.matcher(qry);
-        String projection = matcher.find() ? matcher.group(1) : "";
-        return projection.trim();
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java
deleted file mode 100644
index cfa3801..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package includes classes that integrates with Apache Ignite SQL engine.
- */
-package org.apache.ignite.springdata22.repository.query;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java
deleted file mode 100644
index 33d3757..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteProxyFactory.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.support;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.config.BeanExpressionResolver;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-
-import static org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactory.getRepositoryConfiguration;
-
-/**
- * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
- * Ignite cluster.
- */
-public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
-    /** Spring application expression resolver. */
-    private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
-
-    /** Repositories associated with Ignite proxy. */
-    private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
-
-    /** Spring application context. */
-    private ApplicationContext ctx;
-
-    /** Spring application bean expression context. */
-    private BeanExpressionContext beanExpressionCtx;
-
-    /**
-     * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
-     * @return {@link IgniteProxy} instance.
-     */
-    public IgniteProxy igniteProxy(Class<?> repoInterface) {
-        return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
-    }
-
-    /** {@inheritDoc} */
-    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
-        this.ctx = ctx;
-
-        beanExpressionCtx = new BeanExpressionContext(
-            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
-            null);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void destroy() throws Exception {
-        Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
-
-        Exception destroyE = null;
-
-        for (IgniteProxy proxy : proxies) {
-            if (proxy instanceof AutoCloseable) {
-                try {
-                    ((AutoCloseable)proxy).close();
-                }
-                catch (Exception e) {
-                    if (destroyE == null)
-                        destroyE = e;
-                    else
-                        destroyE.addSuppressed(e);
-                }
-            }
-        }
-
-        if (destroyE != null)
-            throw destroyE;
-    }
-
-    /**
-     * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
-     *
-     * @param repoInterface {@link Class} instance of the repository interface.
-     * @return Instance of {@link IgniteProxy} associated with specified repository.
-     *
-     * @see RepositoryConfig
-     */
-    private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
-        RepositoryConfig repoCfg = getRepositoryConfiguration(repoInterface);
-
-        return Stream.<BeanFinder>of(
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
-            () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
-            () -> ctx.getBean(Ignite.class),
-            () -> ctx.getBean(IgniteClient.class),
-            () -> ctx.getBean(IgniteConfiguration.class),
-            () -> ctx.getBean(ClientConfiguration.class)
-        ).map(BeanFinder::getBean)
-            .filter(Objects::nonNull)
-            .findFirst()
-            .map(IgniteProxy::of)
-            .orElseThrow(() -> {
-                return new IllegalArgumentException("Invalid configuration for repository " +
-                    repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
-                    " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
-                    " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
-                    " ClientConfiguration or IgniteConfiguration bean to application context.");
-            });
-    }
-
-    /**
-     * Evaluates the SpEL expression.
-     *
-     * @param spelExpression SpEL expression
-     * @return The result of evaluation of the SpEL expression.
-     */
-    private String evaluateExpression(String spelExpression) {
-        return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
-    }
-
-    /**
-     * Helper interface that wraps getBean method.
-     */
-    @FunctionalInterface
-    private interface BeanFinder {
-        /**
-         * Get bean.
-         * @return Bean or null if {@link BeansException} was thrown.
-         */
-        default Object getBean() {
-            try {
-                return get();
-            } catch (BeansException ex) {
-                return null;
-            }
-        }
-
-        /**
-         * Get bean.
-         * @return Bean.
-         * @throws BeansException If bean was not found.
-         */
-        Object get() throws BeansException;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java
deleted file mode 100644
index 4494c14..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactory.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.support;
-
-import java.util.Optional;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata22.repository.config.DynamicQueryConfig;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata22.repository.query.IgniteQuery;
-import org.apache.ignite.springdata22.repository.query.IgniteQueryGenerator;
-import org.apache.ignite.springdata22.repository.query.IgniteRepositoryQuery;
-import org.springframework.beans.factory.config.BeanExpressionContext;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.expression.StandardBeanExpressionResolver;
-import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.RepositoryInformation;
-import org.springframework.data.repository.core.RepositoryMetadata;
-import org.springframework.data.repository.core.support.AbstractEntityInformation;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * Crucial for spring-data functionality class. Create proxies for repositories.
- * <p>
- * Supports multiple Ignite Instances on same JVM.
- * <p>
- * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
- *
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-public class IgniteRepositoryFactory extends RepositoryFactorySupport {
-    /** Spring application expression resolver */
-    private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
-
-    /** Spring application bean expression context */
-    private final BeanExpressionContext beanExpressionContext;
-
-    /** Ignite cache proxy instance associated with the current repository. */
-    private final IgniteCacheProxy<?, ?> cache;
-
-    /** Ignite proxy instance associated with the current repository. */
-    private final IgniteProxy ignite;
-
-    /**
-     * @param ctx Spring Application context.
-     * @param repoInterface Repository interface.
-     */
-    public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
-        ignite = ctx.getBean(IgniteProxy.class, repoInterface);
-
-        beanExpressionContext = new BeanExpressionContext(
-            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
-            null);
-
-        RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
-
-        String cacheName = evaluateExpression(cfg.cacheName());
-
-        Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
-            ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
-            " annotation to map this repository to the underlying cache.");
-
-       cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
-
-        if (cache == null) {
-            throw new IllegalArgumentException(
-                "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
-                    + ". Please, add a cache configuration to ignite configuration"
-                    + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
-        return new AbstractEntityInformation<T, ID>(domainClass) {
-            /** {@inheritDoc} */
-            @Override public ID getId(T entity) {
-                return null;
-            }
-
-            /** {@inheritDoc} */
-            @Override public Class<ID> getIdType() {
-                return null;
-            }
-        };
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
-        return IgniteRepositoryImpl.class;
-    }
-
-    /**
-     * Evaluate the SpEL expression
-     *
-     * @param spelExpression SpEL expression
-     * @return the result of execution of the SpEL expression
-     */
-    private String evaluateExpression(String spelExpression) {
-        return (String)resolver.evaluate(spelExpression, beanExpressionContext);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Object getTargetRepository(RepositoryInformation metadata) {
-        return getTargetRepositoryViaReflection(metadata, ignite, cache);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
-        QueryMethodEvaluationContextProvider evaluationContextProvider) {
-        return Optional.of((mtd, metadata, factory, namedQueries) -> {
-            final Query annotation = mtd.getAnnotation(Query.class);
-            if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
-                .dynamicQuery())) {
-
-                String qryStr = annotation.value();
-
-                boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
-                    .textQuery());
-
-                IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
-                    !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
-                    annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
-
-                if (key != QueryLookupStrategy.Key.CREATE) {
-                    return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
-                        annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
-                        evaluationContextProvider);
-                }
-            }
-
-            if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
-                throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
-                    + "a query string via org.apache.ignite.springdata22.repository"
-                    + ".config.Query annotation.");
-            }
-
-            return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
-                cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
-        });
-    }
-
-    /**
-     * @param qry Query string.
-     * @return {@code true} if query is SqlFieldsQuery.
-     */
-    public static boolean isFieldQuery(String qry) {
-        String qryUpperCase = qry.toUpperCase();
-
-        return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
-    }
-
-    /**
-     * Evaluates if the query starts with a clause.<br>
-     * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
-     *
-     * @param qryUpperCase Query string in upper case.
-     * @return {@code true} if query is full SQL statement.
-     */
-    private static boolean isStatement(String qryUpperCase) {
-        return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
-            // update
-            qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
-            // delete
-            qryUpperCase.matches("^\\s*DELETE\\b.*") ||
-            // merge
-            qryUpperCase.matches("^\\s*MERGE\\b.*") ||
-            // insert
-            qryUpperCase.matches("^\\s*INSERT\\b.*");
-    }
-
-    /**
-     * @return Configuration of the specified repository.
-     * @throws IllegalArgumentException If no configuration is specified.
-     * @see RepositoryConfig
-     */
-    static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
-        RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
-
-        Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
-            RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
-
-        return cfg;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java
deleted file mode 100644
index 4f6b7a9..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryFactoryBean.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata22.repository.support;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
-import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-
-/**
- * Apache Ignite repository factory bean.
- * <p>
- * The {@link org.apache.ignite.springdata22.repository.config.RepositoryConfig} requires to define one of the
- * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
- * <ul>
- * <li>{@link Ignite} instance bean</li>
- * <li>{@link IgniteConfiguration} bean</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
- * <ul/>
- *
- * @param <T> Repository type, {@link IgniteRepository}
- * @param <V> Domain object class.
- * @param <K> Domain object key, super expects {@link Serializable}.
- */
-public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
-    extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
-    /** */
-    private ApplicationContext ctx;
-
-    /**
-     * @param repoInterface Repository interface.
-     */
-    protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
-        super(repoInterface);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
-        this.ctx = ctx;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected RepositoryFactorySupport createRepositoryFactory() {
-        return new IgniteRepositoryFactory(ctx, getObjectType());
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java
deleted file mode 100644
index 67a5b98..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/IgniteRepositoryImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata22.repository.support;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.cache.Cache;
-import javax.cache.expiry.ExpiryPolicy;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CachePeekMode;
-import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.jetbrains.annotations.Nullable;
-import org.springframework.context.annotation.Conditional;
-
-/**
- * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
- * {@link IgniteRepositoryFactory}
- *
- * @param <V> the cache value type
- * @param <K> the cache key type
- * @author Apache Ignite Team
- * @author Manuel Núñez (manuel.nunez@hawkore.com)
- */
-@Conditional(ConditionFalse.class)
-public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
-    /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
-    private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
-        " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
-
-    /**
-     * Ignite Cache bound to the repository
-     */
-    private final IgniteCacheProxy<K, V> cache;
-
-    /**
-     * Ignite instance bound to the repository
-     */
-    private final IgniteProxy ignite;
-
-    /**
-     * Repository constructor.
-     *
-     * @param ignite the ignite
-     * @param cache  Initialized cache instance.
-     */
-    public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
-        this.cache = cache;
-        this.ignite = ignite;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteCache<K, V> cache() {
-        if (cache instanceof IgniteNodeCacheProxy)
-            return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
-
-        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
-    }
-
-    /** {@inheritDoc} */
-    @Override public Ignite ignite() {
-        if (ignite instanceof IgniteNodeProxy)
-            return ((IgniteNodeProxy)ignite).delegate();
-
-        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> S save(K key, S entity) {
-        cache.put(key, entity);
-
-        return entity;
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
-        cache.putAll(entities);
-
-        return entities.values();
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
-        if (expiryPlc != null)
-            cache.withExpiryPolicy(expiryPlc).put(key, entity);
-        else
-            cache.put(key, entity);
-        return entity;
-    }
-
-    /** {@inheritDoc} */
-    @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
-        if (expiryPlc != null)
-            cache.withExpiryPolicy(expiryPlc).putAll(entities);
-        else
-            cache.putAll(entities);
-        return entities.values();
-    }
-
-    /**
-     * Not implemented.
-     */
-    @Override public <S extends V> S save(S entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
-    }
-
-    /**
-     * Not implemented.
-     */
-    @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
-        throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public Optional<V> findById(K id) {
-        return Optional.ofNullable(cache.get(id));
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean existsById(K id) {
-        return cache.containsKey(id);
-    }
-
-    /** {@inheritDoc} */
-    @Override public Iterable<V> findAll() {
-        final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
-
-        return new Iterable<V>() {
-            /** */
-            @Override public Iterator<V> iterator() {
-                return new Iterator<V>() {
-                    /** {@inheritDoc} */
-                    @Override public boolean hasNext() {
-                        return iter.hasNext();
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override public V next() {
-                        return iter.next().getValue();
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override public void remove() {
-                        iter.remove();
-                    }
-                };
-            }
-        };
-    }
-
-    /** {@inheritDoc} */
-    @Override public Iterable<V> findAllById(Iterable<K> ids) {
-        if (ids instanceof Set)
-            return cache.getAll((Set<K>)ids).values();
-
-        if (ids instanceof Collection)
-            return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
-
-        TreeSet<K> keys = new TreeSet<>();
-
-        for (K id : ids)
-            keys.add(id);
-
-        return cache.getAll(keys).values();
-    }
-
-    /** {@inheritDoc} */
-    @Override public long count() {
-        return cache.size(CachePeekMode.PRIMARY);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteById(K id) {
-        cache.remove(id);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void delete(V entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAll(Iterable<? extends V> entities) {
-        throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAllById(Iterable<? extends K> ids) {
-        if (ids instanceof Set) {
-            cache.removeAll((Set<K>)ids);
-            return;
-        }
-
-        if (ids instanceof Collection) {
-            cache.removeAll(new HashSet<>((Collection<K>)ids));
-            return;
-        }
-
-        TreeSet<K> keys = new TreeSet<>();
-
-        for (K id : ids)
-            keys.add(id);
-
-        cache.removeAll(keys);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void deleteAll() {
-        cache.clear();
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java b/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java
deleted file mode 100644
index cc15fc7..0000000
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/package-info.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * <!-- Package description. -->
- * Package contains supporting files required by Spring Data framework.
- */
-package org.apache.ignite.springdata22.repository.support;
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
deleted file mode 100644
index ec2e7ca..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data operation with compound key when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCompoundKeyTest extends IgniteSpringDataCompoundKeyTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(CityRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected Ignite ignite() {
-        return ctx.getBean("igniteServerNode", Ignite.class);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
deleted file mode 100644
index 226ee9b..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.GridTestUtils;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-    }
-
-    /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
-    @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
-        GridTestUtils.assertThrows(log,
-            () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
-            "Query of type TextQuery is not supported by thin client. Check" +
-                " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
-                " method configuration or use Ignite node instance to connect to the Ignite cluster.");
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
deleted file mode 100644
index 27d3645..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/** Tests Spring Data query operations when thin client is used for accessing the Ignite cluster. */
-public class IgniteClientSpringDataQueriesSelfTest extends IgniteSpringDataQueriesSelfTest {
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(IgniteClientApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-        repo2 = ctx.getBean(PersonSecondRepository.class);
-        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
-        for (int i = 0; i < CACHE_SIZE; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
deleted file mode 100644
index d3ccf5e..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.springdata.compoundkey.City;
-import org.apache.ignite.springdata.compoundkey.CityKey;
-import org.apache.ignite.springdata.compoundkey.CityRepository;
-import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-
-/**
- * Test with using conpoud key in spring-data
- * */
-public class IgniteSpringDataCompoundKeyTest extends GridCommonAbstractTest {
-    /** Application context */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /** City repository */
-    protected static CityRepository repo;
-
-    /** Cache name */
-    private static final String CACHE_NAME = "City";
-
-    /** Cities count */
-    private static final int TOTAL_COUNT = 5;
-
-    /** Count Afganistan cities */
-    private static final int AFG_COUNT = 4;
-
-    /** Kabul identifier */
-    private static final int KABUL_ID = 1;
-
-    /** Quandahar identifier */
-    private static final int QUANDAHAR_ID = 2;
-
-    /** Afganistan county code */
-    private static final String AFG = "AFG";
-
-    /** test city Kabul */
-    protected static final City KABUL = new City("Kabul", "Kabol", 1780000);
-
-    /** test city Quandahar */
-    private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
-
-    /**
-     * Performs context initialization before tests.
-     */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-        ctx.register(CompoundKeyApplicationConfiguration.class);
-        ctx.refresh();
-
-        repo = ctx.getBean(CityRepository.class);
-    }
-
-    /**
-     * Load data
-     * */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        loadData();
-
-        assertEquals(getTotalCount(), repo.count());
-    }
-
-    /**
-     * Clear data
-     * */
-    @Override protected void afterTest() throws Exception {
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-
-        super.afterTest();
-    }
-
-    /**
-     * Performs context destroy after tests.
-     */
-    @Override protected void afterTestsStopped() {
-        ctx.close();
-    }
-
-    /** Load data. */
-    public void loadData() throws Exception {
-        Ignite ignite = ignite();
-
-        if (ignite.cacheNames().contains(CACHE_NAME))
-            ignite.destroyCache(CACHE_NAME);
-
-        try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:" + CLI_CONN_PORT + '/')) {
-            Statement st = conn.createStatement();
-
-            st.execute("DROP TABLE IF EXISTS City");
-            st.execute("CREATE TABLE City (ID INT, Name VARCHAR, CountryCode CHAR(3), District VARCHAR, Population INT, PRIMARY KEY (ID, CountryCode)) WITH \"template=partitioned, backups=1, affinityKey=CountryCode, CACHE_NAME=City, KEY_TYPE=org.apache.ignite.springdata.compoundkey.CityKey, VALUE_TYPE=org.apache.ignite.springdata.compoundkey.City\"");
-            st.execute("SET STREAMING ON;");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (1,'Kabul','AFG','Kabol',1780000)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (2,'Qandahar','AFG','Qandahar',237500)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (3,'Herat','AFG','Herat',186800)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (4,'Mazar-e-Sharif','AFG','Balkh',127800)");
-            st.execute("INSERT INTO City(ID, Name, CountryCode, District, Population) VALUES (5,'Amsterdam','NLD','Noord-Holland',731200)");
-        }
-    }
-
-    /** Test */
-    @Test
-    public void test() {
-        assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
-        assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
-        assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
-    }
-
-    /** Test. */
-    @Test
-    public void deleteAllById() {
-        Set<CityKey> keys = new HashSet<>();
-        keys.add(new CityKey(1, "AFG"));
-        keys.add(new CityKey(2, "AFG"));
-        keys.add(new CityKey(3, "AFG"));
-        keys.add(new CityKey(4, "AFG"));
-        keys.add(new CityKey(5, "NLD"));
-
-        repo.deleteAllById(keys);
-        assertEquals(0, repo.count());
-    }
-
-    /** */
-    protected Ignite ignite() {
-        return ctx.getBean(Ignite.class);
-    }
-
-    /** Total count of entries after load data. */
-    protected int getTotalCount() {
-        return TOTAL_COUNT;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
deleted file mode 100644
index e11c1c0..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.io.Serializable;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan.Filter;
-import org.springframework.context.annotation.Configuration;
-
-import static org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
-import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE;
-
-/** Tests Spring Data repository cluster connection configurations. */
-public class IgniteSpringDataConnectionConfigurationTest extends GridCommonAbstractTest {
-    /** */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
-    /** */
-    private static final String CACHE_NAME = "PersonCache";
-
-    /** */
-    private static final int CLI_CONN_PORT = 10810;
-
-    /** */
-    private static final String CLI_NAME = "cli-node";
-
-    /** */
-    private static final String SRV_NAME = "srv-node";
-
-    /** */
-    private static final String LOCAL_HOST = "127.0.0.1";
-
-    /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithIgniteConfiguration() {
-        checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
-        assertClientNodeIsStopped();
-    }
-
-    /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithClientConfiguration() {
-        checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
-    }
-
-    /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteInstanceParameter() {
-        checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteClientInstanceParameter() {
-        checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgnitClientConfigurationParameter() {
-        checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
-    @Test
-    public void testRepositoryWithoutIgniteConfigurationParameter() {
-        checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
-    }
-
-    /**
-     * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
-     * used to access the Ignite cluster.
-     */
-    @Test
-    public void testRepositoryWithExistingIgniteInstance() throws Exception {
-        try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
-            checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
-
-            assertNotNull(Ignition.ignite(CLI_NAME));
-        }
-    }
-
-    /** Tests repository configuration in case specified cache name is invalid. */
-    @Test
-    public void testRepositoryWithInvalidCacheNameConfiguration() {
-        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
-            ctx.register(InvalidCacheNameApplication.class);
-
-            assertThrowsAnyCause(log,
-                () -> {
-                    ctx.refresh();
-
-                    return null;
-                },
-                IllegalArgumentException.class,
-                "Cache 'invalidCache' not found for repository interface" +
-                    " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
-                    " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
-                    " org.apache.ignite.springdata22.repository.config.RepositoryConfig annotation.");
-        }
-
-        assertClientNodeIsStopped();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        super.afterTest();
-
-        grid(SRV_NAME).cache(CACHE_NAME).clear();
-    }
-
-    /** */
-    private void assertClientNodeIsStopped() {
-        assertFalse(Ignition.allGrids().stream().map(Ignite::name).anyMatch(CLI_NAME::equals));
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        startGrid(getIgniteConfiguration(SRV_NAME, false));
-    }
-
-    /**
-     * Checks that repository created based on specified Spring application configuration is properly initialized and
-     * got access to the Ignite cluster.
-     */
-    private void checkRepositoryConfiguration(
-        Class<?> cfgCls,
-        Class<? extends IgniteRepository<Object, Serializable>> repoCls
-    ) {
-        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
-            ctx.register(cfgCls);
-            ctx.refresh();
-
-            IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
-
-            IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
-
-            assertEquals(0, repo.count());
-            assertEquals(0, cache.size());
-
-            int key = 0;
-
-            repo.save(key, "1");
-
-            assertEquals(1, repo.count());
-            assertNotNull(cache.get(key));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
-    public static class InvalidCacheNameApplication {
-        /** Ignite configuration bean. */
-        @Bean
-        public IgniteConfiguration igniteConfiguration() {
-            return getIgniteConfiguration(CLI_NAME, true);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
-    public static class IgniteConfigurationApplication {
-        /** Ignite configuration bean. */
-        @Bean
-        public IgniteConfiguration igniteConfiguration() {
-            return getIgniteConfiguration(CLI_NAME, true);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case {@link ClientConfiguration} is used
-     * for accessing the cluster.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
-    public static class ClientConfigurationApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public ClientConfiguration clientConfiguration() {
-            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if Ignite bean name was not provided
-     * through {@link RepositoryConfig#igniteInstance()} ()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteBeanApplication {
-        /** Ignite bean. */
-        @Bean
-        public Ignite someIgnite() {
-            return Ignition.start(getIgniteConfiguration("test", false));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
-     * through {@link RepositoryConfig#igniteInstance()} ()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteClientBeanApplication {
-        /** Ignite client bean. */
-        @Bean
-        public IgniteClient someIgnite() {
-            return Ignition.startClient(new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT));
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
-     * through {@link RepositoryConfig#igniteCfg()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteClientConfigurationBeanApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public ClientConfiguration someCfg() {
-            return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
-        }
-    }
-
-    /**
-     * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
-     * through {@link RepositoryConfig#igniteCfg()}.
-     */
-    @Configuration
-    @EnableIgniteRepositories(
-        considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
-    )
-    public static class DefaultIgniteConfigurationBeanApplication {
-        /** Ignite client configuration bean. */
-        @Bean
-        public IgniteConfiguration someCfg() {
-            return getIgniteConfiguration("test", false);
-        }
-    }
-
-    /** Repository for testing configuration approach through default ignite beans. */
-    @RepositoryConfig(cacheName = "PersonCache")
-    public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
-    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
-    public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
-    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
-    public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
-    @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
-    public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
-        // No-op.
-    }
-
-    /** */
-    private static IgniteConfiguration getIgniteConfiguration(String name, boolean clientMode) {
-        return new IgniteConfiguration()
-            .setIgniteInstanceName(name)
-            .setClientMode(clientMode)
-            .setLocalHost(LOCAL_HOST)
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER))
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
-            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME));
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
deleted file mode 100644
index a543044..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.TreeSet;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.FullNameProjection;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-/**
- * CRUD tests.
- */
-public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
-    /** Repository. */
-    protected static PersonRepository repo;
-
-    /** Context. */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /** Number of entries to store */
-    private static int CACHE_SIZE = 1000;
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(ApplicationConfiguration.class);
-
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        fillInRepository();
-
-        assertEquals(CACHE_SIZE, repo.count());
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-
-        super.afterTest();
-    }
-
-    /** */
-    private void fillInRepository() {
-        for (int i = 0; i < CACHE_SIZE - 5; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-
-        repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        ctx.destroy();
-    }
-
-    /** */
-    @Test
-    public void testPutGet() {
-        Person person = new Person("some_name", "some_surname");
-
-        int id = CACHE_SIZE + 1;
-
-        assertEquals(person, repo.save(id, person));
-
-        assertTrue(repo.existsById(id));
-
-        assertEquals(person, repo.findById(id).get());
-
-        try {
-            repo.save(person);
-
-            fail("Managed to save a Person without ID");
-        }
-        catch (UnsupportedOperationException e) {
-            //excepted
-        }
-    }
-
-    /** */
-    @Test
-    public void testPutAllGetAll() {
-        LinkedHashMap<Integer, Person> map = new LinkedHashMap<>();
-
-        for (int i = CACHE_SIZE; i < CACHE_SIZE + 50; i++)
-            map.put(i, new Person("some_name" + i, "some_surname" + i));
-
-        Iterator<Person> persons = repo.save(map).iterator();
-
-        assertEquals(CACHE_SIZE + 50, repo.count());
-
-        Iterator<Person> origPersons = map.values().iterator();
-
-        while (persons.hasNext())
-            assertEquals(origPersons.next(), persons.next());
-
-        try {
-            repo.saveAll(map.values());
-
-            fail("Managed to save a list of Persons with ids");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-
-        persons = repo.findAllById(map.keySet()).iterator();
-
-        int counter = 0;
-
-        while (persons.hasNext()) {
-            persons.next();
-            counter++;
-        }
-
-        assertEquals(map.size(), counter);
-    }
-
-    /** */
-    @Test
-    public void testGetAll() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        Iterator<Person> persons = repo.findAll().iterator();
-
-        int counter = 0;
-
-        while (persons.hasNext()) {
-            persons.next();
-            counter++;
-        }
-
-        assertEquals(repo.count(), counter);
-    }
-
-    /** */
-    @Test
-    public void testDelete() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        repo.deleteById(0);
-
-        assertEquals(CACHE_SIZE - 1, repo.count());
-        assertEquals(Optional.empty(),repo.findById(0));
-
-        try {
-            repo.delete(new Person("", ""));
-
-            fail("Managed to delete a Person without id");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-    }
-
-    /** */
-    @Test
-    public void testDeleteSet() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        TreeSet<Integer> ids = new TreeSet<>();
-
-        for (int i = 0; i < CACHE_SIZE / 2; i++)
-            ids.add(i);
-
-        repo.deleteAllById(ids);
-
-        assertEquals(CACHE_SIZE / 2, repo.count());
-
-        try {
-            ArrayList<Person> persons = new ArrayList<>();
-
-            for (int i = 0; i < 3; i++)
-                persons.add(new Person(String.valueOf(i), String.valueOf(i)));
-
-            repo.deleteAll(persons);
-
-            fail("Managed to delete Persons without ids");
-        }
-        catch (UnsupportedOperationException e) {
-            //expected
-        }
-    }
-
-    /** */
-    @Test
-    public void testDeleteAll() {
-        assertEquals(CACHE_SIZE, repo.count());
-
-        repo.deleteAll();
-
-        assertEquals(0, repo.count());
-    }
-
-    /**
-     * Delete existing record.
-     */
-    @Test
-    public void testDeleteByFirstName() {
-        assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
-
-        long cnt = repo.deleteByFirstName("uniquePerson");
-
-        assertEquals(1, cnt);
-    }
-
-    /**
-     * Delete NON existing record.
-     */
-    @Test
-    public void testDeleteExpression() {
-        long cnt = repo.deleteByFirstName("880");
-
-        assertEquals(0, cnt);
-    }
-
-    /**
-     * Delete Multiple records due to where.
-     */
-    @Test
-    public void testDeleteExpressionMultiple() {
-        long count = repo.countByFirstName("nonUniquePerson");
-        long cnt = repo.deleteByFirstName("nonUniquePerson");
-
-        assertEquals(cnt, count);
-    }
-
-    /**
-     * Remove should do the same than Delete.
-     */
-    @Test
-    public void testRemoveExpression() {
-        repo.removeByFirstName("person3f");
-
-        long count = repo.count();
-        assertEquals(CACHE_SIZE - 1, count);
-    }
-
-    /**
-     * Delete unique record using lower case key word.
-     */
-    @Test
-    public void testDeleteQuery() {
-        repo.deleteBySecondNameLowerCase("uniqueLastName");
-
-        long countAfter = repo.count();
-        assertEquals(CACHE_SIZE - 1, countAfter);
-    }
-
-    /**
-     * Try to delete with a wrong @Query.
-     */
-    @Test
-    public void testWrongDeleteQuery() {
-        long countBefore = repo.countByFirstNameLike("person3f");
-
-        try {
-            repo.deleteWrongByFirstNameQuery("person3f");
-        }
-        catch (Exception e) {
-            //expected
-        }
-
-        long countAfter = repo.countByFirstNameLike("person3f");
-        assertEquals(countBefore, countAfter);
-    }
-
-    /**
-     * Update with a @Query a record.
-     */
-    @Test
-    public void testUpdateQueryMixedCase() {
-        final String newSecondName = "updatedUniqueSecondName";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<Person> person = repo.findByFirstName("uniquePerson");
-        assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
-    }
-
-    /**
-     * Update with a @Query a record
-     */
-    @Test
-    public void testUpdateQueryMixedCaseProjection() {
-        final String newSecondName = "updatedUniqueSecondName1";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-
-        List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
-        assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
-        final String newSecondName = "updatedUniqueSecondName2";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
-        assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
-
-        FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
-        assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
-        final String newSecondName = "updatedUniqueSecondName3";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
-        final String newSecondName = "updatedUniqueSecondName4";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
-        final String newSecondName = "updatedUniqueSecondName5";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
-    }
-
-    /** */
-    @Test
-    public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
-        final String newSecondName = "updatedUniqueSecondName6";
-        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
-
-        assertEquals(1, cnt);
-
-        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
-        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
-        assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
-    }
-
-    /**
-     * Update with a wrong @Query
-     */
-    @Test
-    public void testWrongUpdateQuery() {
-        final String newSecondName = "updatedUniqueSecondName";
-        int rowsUpdated = 0;
-
-        try {
-            rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
-        }
-        catch (Exception ignored) {
-            //expected
-        }
-
-        assertEquals(0, rowsUpdated);
-
-        List<Person> person = repo.findByFirstName("uniquePerson");
-        assertEquals(person.get(0).getSecondName(), "uniqueLastName");
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
deleted file mode 100644
index 19a9f63..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.cache.Cache;
-import org.apache.ignite.springdata.misc.ApplicationConfiguration;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonProjection;
-import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
-import org.apache.ignite.springdata.misc.PersonSecondRepository;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-import org.springframework.data.domain.Sort;
-
-/**
- *
- */
-public class IgniteSpringDataQueriesSelfTest extends GridCommonAbstractTest {
-    /** Repository. */
-    protected static PersonRepository repo;
-
-    /** Repository 2. */
-    protected static PersonSecondRepository repo2;
-
-    /**
-     * Repository Ignite Instance cluster TWO.
-     */
-    protected static PersonRepositoryOtherIgniteInstance repoTWO;
-
-    /** Context. */
-    protected static AnnotationConfigApplicationContext ctx;
-
-    /**
-     * Number of entries to store
-     */
-    protected static int CACHE_SIZE = 1000;
-
-    /**
-     * Performs context initialization before tests.
-     */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        ctx = new AnnotationConfigApplicationContext();
-
-        ctx.register(ApplicationConfiguration.class);
-
-        ctx.refresh();
-
-        repo = ctx.getBean(PersonRepository.class);
-        repo2 = ctx.getBean(PersonSecondRepository.class);
-        // repository on another ignite instance (and another cluster)
-        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
-
-        for (int i = 0; i < CACHE_SIZE; i++) {
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-        }
-    }
-
-    /**
-     * Performs context destroy after tests.
-     */
-    @Override protected void afterTestsStopped() throws Exception {
-        ctx.destroy();
-    }
-
-    /** */
-    @Test
-    public void testExplicitQuery() {
-        List<Person> persons = repo.simpleQuery("person4a");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("person4a", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testExplicitQueryTWO() {
-        List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("TWOperson4a", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testEqualsPart() {
-        List<Person> persons = repo.findByFirstName("person4e");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("person4e", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testEqualsPartTWO() {
-        List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertEquals("TWOperson4e", person.getFirstName());
-    }
-
-    /** */
-    @Test
-    public void testContainingPart() {
-        List<Person> persons = repo.findByFirstNameContaining("person4");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertTrue(person.getFirstName().startsWith("person4"));
-    }
-
-    /** */
-    @Test
-    public void testContainingPartTWO() {
-        List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
-
-        assertFalse(persons.isEmpty());
-
-        for (Person person : persons)
-            assertTrue(person.getFirstName().startsWith("TWOperson4"));
-    }
-
-    /** */
-    @Test
-    public void testTopPart() {
-        Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
-
-        Iterator<Person> iter = top.iterator();
-
-        Person person = iter.next();
-
-        assertFalse(iter.hasNext());
-
-        assertTrue(person.getFirstName().startsWith("person4"));
-    }
-
-    /** */
-    @Test
-    public void testTopPartTWO() {
-        Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
-
-        Iterator<Person> iter = top.iterator();
-
-        Person person = iter.next();
-
-        assertFalse(iter.hasNext());
-
-        assertTrue(person.getFirstName().startsWith("TWOperson4"));
-    }
-
-    /** */
-    @Test
-    public void testLikeAndLimit() {
-        Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
-
-        int cnt = 0;
-
-        for (Person next : like) {
-            assertTrue(next.getFirstName().contains("person"));
-
-            cnt++;
-        }
-
-        assertEquals(10, cnt);
-    }
-
-    /** */
-    @Test
-    public void testLikeAndLimitTWO() {
-        Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
-
-        int cnt = 0;
-
-        for (Person next : like) {
-            assertTrue(next.getFirstName().contains("TWOperson"));
-
-            cnt++;
-        }
-
-        assertEquals(10, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCount() {
-        int cnt = repo.countByFirstNameLike("person");
-
-        assertEquals(1000, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCountTWO() {
-        int cnt = repoTWO.countByFirstNameLike("TWOperson");
-
-        assertEquals(1000, cnt);
-    }
-
-    /** */
-    @Test
-    public void testCount2() {
-        int cnt = repo.countByFirstNameLike("person4");
-
-        assertTrue(cnt < 1000);
-    }
-
-    /** */
-    @Test
-    public void testCount2TWO() {
-        int cnt = repoTWO.countByFirstNameLike("TWOperson4");
-
-        assertTrue(cnt < 1000);
-    }
-
-    /** */
-    @Test
-    public void testPageable() {
-        PageRequest pageable = PageRequest.of(1, 5, Sort.Direction.DESC, "firstName");
-
-        HashSet<String> firstNames = new HashSet<>();
-
-        List<Person> pageable1 = repo.findByFirstNameRegex("^[a-z]+$", pageable);
-
-        assertEquals(5, pageable1.size());
-
-        for (Person person : pageable1) {
-            firstNames.add(person.getFirstName());
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-        }
-
-        List<Person> pageable2 = repo.findByFirstNameRegex("^[a-z]+$", pageable.next());
-
-        assertEquals(5, pageable2.size());
-
-        for (Person person : pageable2) {
-            firstNames.add(person.getFirstName());
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-        }
-
-        assertEquals(10, firstNames.size());
-    }
-
-    /** */
-    @Test
-    public void testAndAndOr() {
-        int cntAnd = repo.countByFirstNameLikeAndSecondNameLike("person1", "lastName1");
-
-        int cntOr = repo.countByFirstNameStartingWithOrSecondNameStartingWith("person1", "lastName1");
-
-        assertTrue(cntAnd <= cntOr);
-    }
-
-    /** */
-    @Test
-    public void testQueryWithSort() {
-        List<Person> persons = repo.queryWithSort("^[a-z]+$", Sort.by(Sort.Direction.DESC, "secondName"));
-
-        Person previous = persons.get(0);
-
-        for (Person person : persons) {
-            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
-            previous = person;
-        }
-    }
-
-    /** */
-    @Test
-    public void testQueryWithPaging() {
-        List<Person> persons = repo.queryWithPageable("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
-
-        assertEquals(7, persons.size());
-
-        Person previous = persons.get(0);
-
-        for (Person person : persons) {
-            assertTrue(person.getSecondName().compareTo(previous.getSecondName()) <= 0);
-
-            assertTrue(person.getFirstName().matches("^[a-z]+$"));
-
-            previous = person;
-        }
-    }
-
-    /** */
-    @Test
-    public void testQueryFields() {
-        List<String> persons = repo.selectField("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
-
-        assertEquals(7, persons.size());
-    }
-
-    /** */
-    @Test
-    public void testFindCacheEntries() {
-        List<Cache.Entry<Integer, Person>> cacheEntries = repo.findBySecondNameLike("stName1");
-
-        assertFalse(cacheEntries.isEmpty());
-
-        for (Cache.Entry<Integer, Person> entry : cacheEntries)
-            assertTrue(entry.getValue().getSecondName().contains("stName1"));
-    }
-
-    /** */
-    @Test
-    public void testFindOneCacheEntry() {
-        Cache.Entry<Integer, Person> cacheEntry = repo.findTopBySecondNameLike("tName18");
-
-        assertNotNull(cacheEntry);
-
-        assertTrue(cacheEntry.getValue().getSecondName().contains("tName18"));
-    }
-
-    /** */
-    @Test
-    public void testFindOneValue() {
-        PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
-
-        assertNotNull(person);
-
-        assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
-    }
-
-    /** */
-    @Test
-    public void testSelectSeveralFields() {
-        List<List> lists = repo.selectSeveralField("^[a-z]+$", PageRequest.of(2, 6));
-
-        assertEquals(6, lists.size());
-
-        for (List list : lists) {
-            assertEquals(2, list.size());
-
-            assertTrue(list.get(0) instanceof Integer);
-        }
-    }
-
-    /** */
-    @Test
-    public void testCountQuery() {
-        int cnt = repo.countQuery(".*");
-
-        assertEquals(256, cnt);
-    }
-
-    /** */
-    @Test
-    public void testSliceOfCacheEntries() {
-        Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", PageRequest.of(3, 4));
-
-        assertEquals(4, slice.getSize());
-
-        for (Cache.Entry<Integer, Person> entry : slice)
-            assertFalse("lastName18".equals(entry.getValue().getSecondName()));
-    }
-
-    /** */
-    @Test
-    public void testSliceOfLists() {
-        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", PageRequest.of(0, 3));
-
-        assertEquals(3, lists.getSize());
-
-        for (List list : lists) {
-            assertEquals(2, list.size());
-
-            assertTrue(list.get(0) instanceof Integer);
-        }
-    }
-
-    /** Tests conversion of SQL select query result to domain entity objects. */
-    @Test
-    public void testRowToEntityConversion() {
-        Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
-
-        Set<Person> exp = new HashSet<>();
-
-        repo.findAll().forEach(exp::add);
-
-        assertEquals(exp, res);
-    }
-
-    /**
-     * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
-     * of domain entity class.
-     */
-    @Test
-    public void testIncompleteRowToEntityConversion() {
-        Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
-
-        Set<Person> exp = new HashSet<>();
-
-        repo.findAll().forEach(p -> {
-            p.setSecondName(null);
-
-            exp.add(p);
-        });
-
-        assertEquals(exp, res);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
deleted file mode 100644
index e86a575..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/City.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.Objects;
-
-/**
- * Value-class
- * */
-public class City {
-    /** City name */
-    private String name;
-
-    /** City district */
-    private String district;
-
-    /** City population */
-    private int population;
-
-    /**
-     * @param name city name
-     * @param district city district
-     * @param population city population
-     * */
-    public City(String name, String district, int population) {
-        this.name = name;
-        this.district = district;
-        this.population = population;
-    }
-
-    /**
-     * @return city name
-     * */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @param name city name
-     * */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * @return city district
-     * */
-    public String getDistrict() {
-        return district;
-    }
-
-    /**
-     * @param district city district
-     * */
-    public void setDistrict(String district) {
-        this.district = district;
-    }
-
-    /**
-     * @return city population
-     * */
-    public int getPopulation() {
-        return population;
-    }
-
-    /**
-     * @param population city population
-     * */
-    public void setPopulation(int population) {
-        this.population = population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return name + " | " + district + " | " + population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        City city = (City)o;
-
-        return
-                Objects.equals(this.name, city.name) &&
-                        Objects.equals(this.district, city.district) &&
-                        this.population == city.population;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(name, district, population);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
deleted file mode 100644
index 88226fe..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKey.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.io.Serializable;
-import java.util.Objects;
-import org.apache.ignite.cache.affinity.AffinityKeyMapped;
-
-/** Compound key for city class  */
-public class CityKey implements Serializable {
-    /** city identifier */
-    private int ID;
-
-    /** affinity key countrycode  */
-    @AffinityKeyMapped
-    private String COUNTRYCODE;
-
-    /**
-     * @param id city identifier
-     * @param countryCode city countrycode
-     * */
-    public CityKey(int id, String countryCode) {
-        this.ID = id;
-        this.COUNTRYCODE = countryCode;
-    }
-
-    /**
-     * @return city id
-     * */
-    public int getId() {
-        return ID;
-    }
-
-    /**
-     * @return countrycode
-     * */
-    public String getCountryCode() {
-        return COUNTRYCODE;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        CityKey key = (CityKey)o;
-
-        return ID == key.ID &&
-                COUNTRYCODE.equals(key.COUNTRYCODE);
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(ID, COUNTRYCODE);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return ID + " | " + COUNTRYCODE;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
deleted file mode 100644
index ab745e7..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import java.util.List;
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.stereotype.Repository;
-
-/** City repository */
-@Repository
-@RepositoryConfig(cacheName = "City", autoCreateCache = true)
-public interface CityRepository extends IgniteRepository<City, CityKey> {
-    /**
-     * Find city by id
-     * @param id city identifier
-     * @return city
-     * */
-    public City findById(int id);
-
-    /**
-     * Find all cities by coutrycode
-     * @param cc coutrycode
-     * @return list of cache enrties CityKey -> City
-     * */
-    public List<Cache.Entry<CityKey, City>> findByCountryCode(String cc);
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
deleted file mode 100644
index 2d472a2..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CompoundKeyApplicationConfiguration.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.compoundkey;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Spring application configuration
- * */
-@Configuration
-@EnableIgniteRepositories
-public class CompoundKeyApplicationConfiguration {
-    /** */
-    public static final int CLI_CONN_PORT = 10810;
-
-    /**
-     * Ignite instance bean
-     * */
-    @Bean
-    public Ignite igniteInstance() {
-        return Ignition.start(new IgniteConfiguration()
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT)));
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
deleted file mode 100644
index 1443d5d..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.spel.spi.EvaluationContextExtension;
-
-/** */
-@Configuration
-@EnableIgniteRepositories
-public class ApplicationConfiguration {
-    /** */
-    public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
-
-    /** */
-    public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
-
-    /**
-     * The bean with cache names
-     */
-    @Bean
-    public CacheNamesBean cacheNames() {
-        CacheNamesBean bean = new CacheNamesBean();
-
-        bean.setPersonCacheName("PersonCache");
-
-        return bean;
-    }
-
-    /** */
-    @Bean
-    public EvaluationContextExtension sampleSpELExtension() {
-        return new SampleEvaluationContextExtension();
-    }
-
-    /** */
-    @Bean(value = "sampleExtensionBean")
-    public SamplePassParamExtension sampleExtensionBean() {
-        return new SamplePassParamExtension();
-    }
-
-    /**
-     * Ignite instance bean - no instance name provided on RepositoryConfig
-     */
-    @Bean
-    public Ignite igniteInstance() {
-        IgniteConfiguration cfg = new IgniteConfiguration();
-
-        cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
-
-        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
-        ccfg.setIndexedTypes(Integer.class, Person.class);
-
-        cfg.setCacheConfiguration(ccfg);
-
-        TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
-        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
-        cfg.setDiscoverySpi(spi);
-
-        return Ignition.start(cfg);
-    }
-
-    /**
-     * Ignite instance bean with not default name
-     */
-    @Bean
-    public Ignite igniteInstanceTWO() {
-        IgniteConfiguration cfg = new IgniteConfiguration();
-
-        cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
-
-        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
-
-        ccfg.setIndexedTypes(Integer.class, Person.class);
-
-        cfg.setCacheConfiguration(ccfg);
-
-        TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
-        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
-
-        cfg.setDiscoverySpi(spi);
-
-        return Ignition.start(cfg);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
deleted file mode 100644
index 6185744..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-/**
- * The bean with cache names.
- */
-public class CacheNamesBean {
-    /** */
-    private String personCacheName;
-
-    /**
-     * Get name of cache for persons.
-     *
-     * @return Name of cache.
-     */
-    public String getPersonCacheName() {
-        return personCacheName;
-    }
-
-    /**
-     * @param personCacheName Name of cache.
-     */
-    public void setPersonCacheName(String personCacheName) {
-        this.personCacheName = personCacheName;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
deleted file mode 100644
index 23f8f8e..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import org.springframework.beans.factory.annotation.Value;
-
-/**
- * Advanced SpEl Expressions into projection
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public interface FullNameProjection {
-    /**
-     * Sample of using SpEL expression
-     * @return
-     */
-    @Value("#{target.firstName + ' ' + target.secondName}")
-    String getFullName();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
deleted file mode 100644
index ad255d0..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.Ignite;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.BinaryConfiguration;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.configuration.ClientConnectorConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.spel.spi.EvaluationContextExtension;
-
-import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
-import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
-
-/** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
-@Configuration
-@EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
-public class IgniteClientApplicationConfiguration {
-    /** Test cache name. */
-    public static final String CACHE_NAME = "PersonCache";
-
-    /** */
-    @Bean
-    public CacheNamesBean cacheNames() {
-        CacheNamesBean bean = new CacheNamesBean();
-
-        bean.setPersonCacheName(CACHE_NAME);
-
-        return bean;
-    }
-
-    /** */
-    @Bean
-    public EvaluationContextExtension sampleSpELExtension() {
-        return new SampleEvaluationContextExtension();
-    }
-
-    /** */
-    @Bean(value = "sampleExtensionBean")
-    public SamplePassParamExtension sampleExtensionBean() {
-        return new SamplePassParamExtension();
-    }
-
-    /** */
-    @Bean
-    public Ignite igniteServerNode() {
-        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
-    }
-
-    /** */
-    @Bean
-    public Ignite igniteSecondServerNode() {
-        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
-    }
-
-    /** Ignite client instance bean with default name. */
-    @Bean
-    public IgniteClient igniteInstance() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
-            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
-    }
-
-    /** Ignite client instance bean with non-default name. */
-    @Bean
-    public IgniteClient igniteInstanceTWO() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
-    }
-
-    /** */
-    private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
-        return new IgniteConfiguration()
-            .setIgniteInstanceName(igniteInstanceName)
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
-            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
-            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
deleted file mode 100644
index 62c3054..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Date;
-import java.util.Objects;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
-
-/**
- * DTO class.
- */
-public class Person {
-    /** First name. */
-    @QuerySqlField(index = true)
-    @QueryTextField
-    private String firstName;
-
-    /** Second name. */
-    @QuerySqlField(index = true)
-    private String secondName;
-
-    /** Birthday. */
-    @QuerySqlField
-    private Date birthday;
-
-    /**
-     * @param firstName First name.
-     * @param secondName Second name.
-     */
-    public Person(String firstName, String secondName) {
-        this.firstName = firstName;
-        this.secondName = secondName;
-        birthday = new Date();
-    }
-
-    /**
-     * @return First name.
-     */
-    public String getFirstName() {
-        return firstName;
-    }
-
-    /**
-     * @param firstName First name.
-     */
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    /**
-     * @return Second name.
-     */
-    public String getSecondName() {
-        return secondName;
-    }
-
-    /**
-     * @param secondName Second name.
-     */
-    public void setSecondName(String secondName) {
-        this.secondName = secondName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Person{" +
-            "firstName='" + firstName + '\'' +
-            ", secondName='" + secondName + '\'' +
-            ", birthday='" + birthday + '\'' +
-            '}';
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (o == null || getClass() != o.getClass())
-            return false;
-
-        Person person = (Person)o;
-
-        return Objects.equals(firstName, person.firstName) &&
-            Objects.equals(secondName, person.secondName) &&
-            Objects.equals(birthday, person.birthday);
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(firstName, secondName, birthday);
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
deleted file mode 100644
index 689f856..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-
-/**
- *
- */
-@RepositoryConfig(cacheName = "#{cacheNames.personCacheName}")
-public interface PersonExpressionRepository extends IgniteRepository<Person, Integer> {
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
deleted file mode 100644
index 2537c57..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonKey.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.io.Serializable;
-
-/**
- * Compound key.
- */
-public class PersonKey implements Serializable {
-    /** */
-    private int id1;
-
-    /** */
-    private int id2;
-
-    /**
-     * @param id1 ID1.
-     * @param id2 ID2.
-     */
-    public PersonKey(int id1, int id2) {
-        this.id1 = id1;
-        this.id2 = id2;
-    }
-
-    /**
-     * @return ID1
-     */
-    public int getId1() {
-        return id1;
-    }
-
-    /**
-     * @return ID1
-     */
-    public int getId2() {
-        return id1;
-    }
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
deleted file mode 100644
index a187a08..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.ignite.springdata.misc;
-
-import org.springframework.beans.factory.annotation.Value;
-
-/**
- * Advanced SpEl Expressions into projection
- *
- * @author Manuel Núñez Sánchez (manuel.nunez@hawkore.com)
- */
-public interface PersonProjection {
-    /** */
-    String getFirstName();
-
-    /**
-     * Sample of using registered spring bean into SpEL expression
-     * @return
-     */
-    @Value("#{@sampleExtensionBean.transformParam(target.firstName)}")
-    String getFirstNameTransformed();
-
-    /**
-     * Sample of using SpEL expression
-     * @return
-     */
-    @Value("#{target.firstName + ' ' + target.secondName}")
-    String getFullName();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
deleted file mode 100644
index 4fd3e07..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ /dev/null
@@ -1,159 +0,0 @@
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.repository.query.Param;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonRepository extends IgniteRepository<Person, Integer> {
-    /** */
-    public List<Person> findByFirstName(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<PersonProjection> queryByFirstNameWithProjection(String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
-    /** */
-    @Query("firstName = :firstname")
-    public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
-
-    /** */
-    @Query("firstName = ?#{[1]}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
-
-    /** */
-    @Query(textQuery = true, value = "#{#firstname}", limit = 2)
-    public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
-
-    @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
-
-    @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
-    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
-
-    /** */
-    public List<Person> findByFirstNameContaining(String val);
-
-    /** */
-    public List<Person> findByFirstNameRegex(String val, Pageable pageable);
-
-    /** */
-    public Collection<Person> findTopByFirstNameContaining(String val);
-
-    /** */
-    public Iterable<Person> findFirst10ByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstName(String val);
-
-    /** */
-    public int countByFirstNameLike(String val);
-
-    /** */
-    public int countByFirstNameLikeAndSecondNameLike(String like1, String like2);
-
-    /** */
-    public int countByFirstNameStartingWithOrSecondNameStartingWith(String like1, String like2);
-
-    /** */
-    public List<Cache.Entry<Integer, Person>> findBySecondNameLike(String val);
-
-    /** */
-    public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
-
-    /** */
-    public PersonProjection findTopBySecondNameStartingWith(String val);
-
-    /** */
-    @Query("firstName = ?")
-    public List<Person> simpleQuery(String val);
-
-    /** */
-    @Query("firstName REGEXP ?")
-    public List<Person> queryWithSort(String val, Sort sort);
-
-    /** */
-    @Query("SELECT * FROM Person WHERE firstName REGEXP ?")
-    public List<Person> queryWithPageable(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT secondName FROM Person WHERE firstName REGEXP ?")
-    public List<String> selectField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
-    public List<List> selectSeveralField(String val, Pageable pageable);
-
-    /** */
-    @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
-    public int countQuery(String val);
-
-    /** Top 3 query */
-    public List<Person> findTop3ByFirstName(String val);
-
-    /** Delete query */
-    public long deleteByFirstName(String firstName);
-
-    /** Remove Query */
-    public List<Person> removeByFirstName(String firstName);
-
-    /** Delete using @Query with keyword in lower-case */
-    @Query("delete FROM Person WHERE secondName = ?")
-    public void deleteBySecondNameLowerCase(String secondName);
-
-    /** Delete using @Query but with errors on the query */
-    @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public void deleteWrongByFirstNameQuery(String firstName);
-
-    /** Update using @Query with keyword in mixed-case */
-    @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
-    public int setFixedSecondNameMixedCase(String secondName, String firstName);
-
-    /** Update using @Query but with errors on the query */
-    @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
-    public int setWrongFixedSecondName(String secondName, String firstName);
-
-    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
-    @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
-    public List<Person> queryWithRowToEntityConversion();
-
-    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
-    @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
-    public List<Person> queryWithIncompleteRowToEntityConversion();
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
deleted file mode 100644
index 97b0b5f..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
-public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
deleted file mode 100644
index 24f1c61..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.springdata.misc;
-
-import java.util.List;
-
-import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
-import org.springframework.data.domain.AbstractPageRequest;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Slice;
-
-/**
- * Test repository.
- */
-@RepositoryConfig(cacheName = "PersonCache")
-public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
-    /** */
-    public Slice<Cache.Entry<Integer, Person>> findBySecondNameIsNot(String val, PageRequest pageReq);
-
-    /** */
-    @Query("SELECT _key, secondName FROM Person WHERE firstName REGEXP ?")
-    public Slice<List> querySliceOfList(String val, AbstractPageRequest pageReq);
-}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java b/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java
deleted file mode 100644
index 86f97b2..0000000
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringData22TestSuite.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.testsuites;
-
-import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundExtendedKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
-import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
-import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
-import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-/**
- * Ignite Spring Data 2.2 test suite.
- */
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
-    IgniteSpringDataCrudSelfTest.class,
-    IgniteSpringDataQueriesSelfTest.class,
-    IgniteSpringDataCrudSelfExpressionTest.class,
-    IgniteSpringDataCompoundKeyTest.class,
-    IgniteSpringDataCompoundExtendedKeyTest.class,
-    IgniteSpringDataConnectionConfigurationTest.class,
-    IgniteClientSpringDataCrudSelfTest.class,
-    IgniteClientSpringDataQueriesSelfTest.class,
-    IgniteClientSpringDataCompoundKeyTest.class
-})
-public class IgniteSpringData22TestSuite {
-}
diff --git a/modules/spring-data-ext/README.txt b/modules/spring-data-ext/README.txt
index eb7aad9..6d5e0e6 100644
--- a/modules/spring-data-ext/README.txt
+++ b/modules/spring-data-ext/README.txt
@@ -3,7 +3,22 @@
 
 Apache Ignite Spring Data extension provides an integration with Spring Data framework.
 
-Importing Spring Data Module In Maven Project
+Main features:
+
+- Supports multiple Ignite instances on same JVM (@RepositoryConfig).
+- Supports query tuning parameters in @Query annotation
+- Supports projections
+- Supports Page and Stream responses
+- Supports Sql Fields Query resultset transformation into the domain entity
+- Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam")
+- Supports advanced parameter binding and SpEL expressions into SQL queries:
+- Template variables:
+    - #entityName - the simple class name of the domain entity
+- Method parameter expressions: Parameters are exposed for indexed access ([0] is the first query method's param) or via the name declared using @Param. The actual SpEL expression binding is triggered by ?#. Example: ?#{[0] or ?#{#myParamName}
+- Advanced SpEL expressions: While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components through SpEL EvaluationContext extension model.
+- Supports SpEL expressions into Text queries (TextQuery).
+
+Importing Spring Data extension In Maven Project
 ----------------------------------------
 
 If you are using Maven to manage dependencies of your project, you can add Spring Data extension
diff --git a/modules/spring-data-2.0-ext/examples/config/example-default.xml b/modules/spring-data-ext/examples/config/example-default.xml
similarity index 100%
rename from modules/spring-data-2.0-ext/examples/config/example-default.xml
rename to modules/spring-data-ext/examples/config/example-default.xml
diff --git a/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml b/modules/spring-data-ext/examples/config/example-spring-data.xml
similarity index 95%
rename from modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
rename to modules/spring-data-ext/examples/config/example-spring-data.xml
index 9f7d674..caaa7f8 100644
--- a/modules/spring-data-2.2-ext/examples/config/example-spring-data.xml
+++ b/modules/spring-data-ext/examples/config/example-spring-data.xml
@@ -26,10 +26,10 @@
     Use this configuration file when running Spring Data examples.
 
     When starting a standalone node, you need to execute the following command:
-    {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-2.2/examples/config/example-spring-data.xml
+    {IGNITE_HOME}/bin/ignite.{bat|sh} modules/spring-data-ext/examples/config/example-spring-data.xml
 
     When starting Ignite from Java IDE, pass path to this file to Ignition:
-    Ignition.start("modules/spring-data-2.2/examples/config/example-spring-data.xml");
+    Ignition.start("modules/spring-data-ext/examples/config/example-spring-data.xml");
 -->
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
diff --git a/modules/spring-data-2.0-ext/examples/pom.xml b/modules/spring-data-ext/examples/pom.xml
similarity index 86%
rename from modules/spring-data-2.0-ext/examples/pom.xml
rename to modules/spring-data-ext/examples/pom.xml
index 72696ee..d29e9f2 100644
--- a/modules/spring-data-2.0-ext/examples/pom.xml
+++ b/modules/spring-data-ext/examples/pom.xml
@@ -32,15 +32,15 @@
         <relativePath>../../../parent</relativePath>
     </parent>
 
-    <artifactId>ignite-spring-data-2.0-ext-examples</artifactId>
-    <version>${ignite-spring-data-2.0-ext.version}</version>
+    <artifactId>ignite-spring-data-ext-examples</artifactId>
+    <version>${ignite-spring-data-ext.version}</version>
     <url>http://ignite.apache.org</url>
 
     <dependencies>
         <dependency>
             <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-spring-data-2.0-ext</artifactId>
-            <version>${ignite-spring-data-2.0-ext.version}</version>
+            <artifactId>ignite-spring-data-ext</artifactId>
+            <version>${ignite-spring-data-ext.version}</version>
         </dependency>
 
         <dependency>
@@ -56,6 +56,24 @@
         </dependency>
 
         <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+            <version>${spring.data-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-spring</artifactId>
             <version>${ignite.version}</version>
@@ -66,23 +84,5 @@
                 </exclusion>
             </exclusions>
         </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring-5.0.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-tx</artifactId>
-            <version>${spring-5.0.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework.data</groupId>
-            <artifactId>spring-data-commons</artifactId>
-            <version>${spring.data-2.0.version}</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
similarity index 91%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
index 72d8eaa..8c4f253 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/IgniteClientSpringApplicationConfiguration.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/IgniteClientSpringApplicationConfiguration.java
@@ -15,13 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
 
 import org.apache.ignite.Ignition;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.configuration.ClientConfiguration;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
similarity index 86%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
index 24b8bdb..007eefc 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/PersonRepository.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/PersonRepository.java
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
 
 import java.util.List;
 import javax.cache.Cache;
-import org.apache.ignite.springdata22.examples.model.Person;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.examples.model.Person;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.springframework.data.domain.Pageable;
 
 /**
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
similarity index 83%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
index d3ca61e..e1c07ff 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringApplicationConfiguration.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringApplicationConfiguration.java
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
 
 import org.apache.ignite.Ignite;
 import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.EnableIgniteRepositories;
-import org.apache.ignite.springdata22.repository.support.IgniteRepositoryFactoryBean;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
+import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -46,6 +46,6 @@
      */
     @Bean
     public Ignite igniteInstance() {
-        return Ignition.start("modules/spring-data-2.2-ext/examples/config/example-spring-data.xml");
+        return Ignition.start("modules/spring-data-ext/examples/config/example-spring-data.xml");
     }
 }
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
index f585673..23278e3 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/SpringDataExample.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/SpringDataExample.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples;
+package org.apache.ignite.springdata.examples;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -26,7 +26,7 @@
 import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata22.examples.model.Person;
+import org.apache.ignite.springdata.examples.model.Person;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.data.domain.PageRequest;
 
@@ -34,7 +34,7 @@
  * The example demonstrates how to interact with an Apache Ignite cluster by means of Spring Data API.
  *
  * Additional cluster nodes can be started with special configuration file which
- * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data-2.2/examples/config/example-spring-data.xml'}.
+ * enables P2P class loading: {@code 'ignite.{sh|bat} modules/spring-data/examples/config/example-spring-data.xml'}.
  */
 public class SpringDataExample {
     /** Spring Application Context. */
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
index 6e00981..2e5c119 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Address.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Address.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryReader;
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
similarity index 97%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
index 12a99fa..5b4082e 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/Employee.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Employee.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 import java.util.Collection;
 
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
similarity index 97%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
index 5d16ebd..5b17a56 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/EmployeeKey.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/EmployeeKey.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 import org.apache.ignite.cache.affinity.AffinityKeyMapped;
 
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
similarity index 97%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
index d06e05c..51bbb25 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Organization.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Organization.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 import java.sql.Timestamp;
 import java.util.concurrent.atomic.AtomicLong;
diff --git a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
similarity index 94%
rename from modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
index 140ff4e..0dae708 100644
--- a/modules/spring-data-2.2-ext/examples/src/main/java/org/apache/ignite/springdata22/examples/model/OrganizationType.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/OrganizationType.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 /**
  * Organization type enum.
diff --git a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
similarity index 98%
rename from modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java
rename to modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
index e9250be..22d2b6c 100644
--- a/modules/spring-data-2.0-ext/examples/src/main/java/org/apache/ignite/springdata20/examples/model/Person.java
+++ b/modules/spring-data-ext/examples/src/main/java/org/apache/ignite/springdata/examples/model/Person.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata20.examples.model;
+package org.apache.ignite.springdata.examples.model;
 
 import java.io.Serializable;
 import java.util.concurrent.atomic.AtomicLong;
diff --git a/modules/spring-data-ext/pom.xml b/modules/spring-data-ext/pom.xml
index 854ff5f..da5b1e2 100644
--- a/modules/spring-data-ext/pom.xml
+++ b/modules/spring-data-ext/pom.xml
@@ -84,11 +84,9 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.ignite</groupId>
-            <artifactId>ignite-core</artifactId>
-            <version>${ignite.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>${commons.lang.version}</version>
         </dependency>
 
         <dependency>
@@ -100,6 +98,14 @@
 
         <dependency>
             <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${ignite.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-spring</artifactId>
             <version>${ignite.version}</version>
             <scope>test</scope>
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
index 472d2e0..d55cf6a 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/IgniteRepository.java
@@ -18,41 +18,92 @@
 
 import java.io.Serializable;
 import java.util.Map;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.jetbrains.annotations.Nullable;
 import org.springframework.data.repository.CrudRepository;
 
 /**
  * Apache Ignite repository that extends basic capabilities of {@link CrudRepository}.
+ *
+ * @param <V> the cache value type
+ * @param <K> the cache key type
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
-public interface IgniteRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
+public interface IgniteRepository<V, K extends Serializable> extends CrudRepository<V, K> {
+    /**
+     * Returns the Ignite instance bound to the repository
+     *
+     * @return the Ignite instance bound to the repository
+     */
+    public Ignite ignite();
+
+    /**
+     * Returns the Ignite Cache bound to the repository
+     *
+     * @return the Ignite Cache bound to the repository
+     */
+    public IgniteCache<K, V> cache();
+
     /**
      * Saves a given entity using provided key.
      * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates
-     * IDs (keys) that are not unique cluster wide.
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+     * (keys) that are not unique cluster wide.
      *
-     * @param key Entity's key.
+     * @param <S>    Entity type.
+     * @param key    Entity's key.
      * @param entity Entity to save.
-     * @param <S> Entity type.
      * @return Saved entity.
      */
-    <S extends T> S save(ID key, S entity);
+    public <S extends V> S save(K key, S entity);
 
     /**
      * Saves all given keys and entities combinations.
      * </p>
-     * It's suggested to use this method instead of default {@link CrudRepository#save(Iterable)} that generates
-     * IDs (keys) that are not unique cluster wide.
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+     * (keys) that are not unique cluster wide.
      *
+     * @param <S>      Type of entities.
      * @param entities Map of key-entities pairs to save.
-     * @param <S> type of entities.
      * @return Saved entities.
      */
-    <S extends T> Iterable<S> save(Map<ID, S> entities);
+    public <S extends V> Iterable<S> save(Map<K, S> entities);
+
+    /**
+     * Saves a given entity using provided key with expiry policy
+     * </p>
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+     * (keys) that are not unique cluster wide.
+     *
+     * @param <S>       Entity type.
+     * @param key       Entity's key.
+     * @param entity    Entity to save.
+     * @param expiryPlc ExpiryPolicy to apply, if not null.
+     * @return Saved entity.
+     */
+    public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc);
+
+    /**
+     * Saves all given keys and entities combinations with expiry policy
+     * </p>
+     * It's suggested to use this method instead of default {@link CrudRepository#save(Object)} that generates IDs
+     * (keys) that are not unique cluster wide.
+     *
+     * @param <S>       Type of entities.
+     * @param entities  Map of key-entities pairs to save.
+     * @param expiryPlc ExpiryPolicy to apply, if not null.
+     * @return Saved entities.
+     */
+    public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc);
 
     /**
      * Deletes all the entities for the provided ids.
      *
      * @param ids List of ids to delete.
      */
-    void deleteAll(Iterable<ID> ids);
+    public void deleteAllById(Iterable<? extends K> ids);
+
 }
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
similarity index 99%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
index f915267..c4d2fd4 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/config/DynamicQueryConfig.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/DynamicQueryConfig.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.ignite.springdata22.repository.config;
+package org.apache.ignite.springdata.repository.config;
 
 /**
  * Runtime Dynamic query configuration.
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
index f73fc3d..fba390b 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/EnableIgniteRepositories.java
@@ -97,8 +97,8 @@
     Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;
 
     /**
-     * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
-     * {@link IgniteRepositoryFactoryBean}.
+     * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to {@link
+     * IgniteRepositoryFactoryBean}.
      *
      * @return {@link FactoryBean} class to be used for each repository instance.
      */
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
index 0f65c32..26b7dc1 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoriesRegistar.java
@@ -17,6 +17,7 @@
 package org.apache.ignite.springdata.repository.config;
 
 import java.lang.annotation.Annotation;
+
 import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
 import org.springframework.data.repository.config.RepositoryConfigurationExtension;
 
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
index 6f21b59..8451118 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/IgniteRepositoryConfigurationExtension.java
@@ -18,6 +18,7 @@
 
 import java.util.Collection;
 import java.util.Collections;
+import org.apache.ignite.springdata.proxy.IgniteProxy;
 import org.apache.ignite.springdata.repository.IgniteRepository;
 import org.apache.ignite.springdata.repository.support.IgniteProxyFactory;
 import org.apache.ignite.springdata.repository.support.IgniteRepositoryFactoryBean;
@@ -27,6 +28,8 @@
 import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
 import org.springframework.data.repository.config.RepositoryConfigurationSource;
 
+import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE;
+
 /**
  * Apache Ignite specific implementation of {@link RepositoryConfigurationExtension}.
  */
@@ -34,6 +37,9 @@
     /** Name of the auto-registered Ignite proxy factory bean. */
     private static final String IGNITE_PROXY_FACTORY_BEAN_NAME = "igniteProxyFactory";
 
+    /** Name of the auto-registered Ignite proxy bean prototype. */
+    private static final String IGNITE_PROXY_BEAN_NAME = "igniteProxy";
+
     /** {@inheritDoc} */
     @Override public String getModuleName() {
         return "Apache Ignite";
@@ -45,21 +51,30 @@
     }
 
     /** {@inheritDoc} */
-    @Override public String getRepositoryFactoryClassName() {
+    @Override public String getRepositoryFactoryBeanClassName() {
         return IgniteRepositoryFactoryBean.class.getName();
     }
 
     /** {@inheritDoc} */
     @Override protected Collection<Class<?>> getIdentifyingTypes() {
-        return Collections.<Class<?>>singleton(IgniteRepository.class);
+        return Collections.singleton(IgniteRepository.class);
     }
 
     /** {@inheritDoc} */
     @Override public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource cfg) {
         registerIfNotAlreadyRegistered(
-            BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
+            () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxyFactory.class).getBeanDefinition(),
             registry,
             IGNITE_PROXY_FACTORY_BEAN_NAME,
             cfg);
+
+        registerIfNotAlreadyRegistered(
+            () -> BeanDefinitionBuilder.genericBeanDefinition(IgniteProxy.class)
+                .setScope(SCOPE_PROTOTYPE)
+                .setFactoryMethodOnBean("igniteProxy", IGNITE_PROXY_FACTORY_BEAN_NAME)
+                .getBeanDefinition(),
+            registry,
+            IGNITE_PROXY_BEAN_NAME,
+            cfg);
     }
 }
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
index 1095942..0e6bf20 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/Query.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.ignite.springdata.repository.config;
 
 import java.lang.annotation.Documented;
@@ -22,16 +21,121 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.client.IgniteClient;
 
 /**
- * Annotation to provide a user defined SQL query for a method.
+ * Annotation to provide a user defined query for a method.
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Query {
     /**
-     * SQL query text string.
+     * Query text string. If not provided, Ignite query generator for Spring Data framework will be used to generate one
+     * (only if textQuery = false (default))
      */
     String value() default "";
+
+    /**
+     * Whether annotated repository method must use TextQuery search. Note that text queries are not supported if
+     * {@link IgniteClient} is used for accessing the Ignite cluster, use {@link Ignite} node instance instead.
+     *
+     * @see RepositoryConfig#igniteInstance()
+     */
+    boolean textQuery() default false;
+
+    /**
+     * Force SqlFieldsQuery type, deactivating auto-detection based on SELECT statement. Useful for non SELECT
+     * statements or to not return hidden fields on SELECT * statements.
+     */
+    boolean forceFieldsQuery() default false;
+
+    /**
+     * Sets flag defining if this query is collocated.
+     * <p>
+     * Collocation flag is used for optimization purposes of queries with GROUP BY statements. Whenever Ignite executes
+     * a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements
+     * of your query selection are collocated together on the same node and you group by collocated key (primary or
+     * affinity key), then Ignite can make significant performance and network optimizations by grouping data on remote
+     * nodes.
+     *
+     * <p>
+     * Only applicable to SqlFieldsQuery
+     */
+    boolean collocated() default false;
+
+    /**
+     * Query timeout in millis. Sets the query execution timeout. Query will be automatically cancelled if the execution
+     * timeout is exceeded. Zero value disables timeout
+     *
+     * <p>
+     * Only applicable to SqlFieldsQuery and SqlQuery
+     */
+    int timeout() default 0;
+
+    /**
+     * Sets flag to enforce join order of tables in the query. If set to {@code true} query optimizer will not reorder
+     * tables in join. By default is {@code false}.
+     * <p>
+     * It is not recommended to enable this property until you are sure that your indexes and the query itself are
+     * correct and tuned as much as possible but query optimizer still produces wrong join order.
+     *
+     * <p>
+     * Only applicable to SqlFieldsQuery
+     */
+    boolean enforceJoinOrder() default false;
+
+    /**
+     * Specify if distributed joins are enabled for this query.
+     * <p>
+     * Only applicable to SqlFieldsQuery and SqlQuery
+     */
+    boolean distributedJoins() default false;
+
+    /**
+     * Sets lazy query execution flag.
+     * <p>
+     * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and
+     * medium result sets this provides optimal performance and minimize duration of internal database locks, thus
+     * increasing concurrency.
+     * <p>
+     * If result set is too big to fit in available memory this could lead to excessive GC pauses and even
+     * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing memory
+     * consumption at the cost of moderate performance hit.
+     * <p>
+     * Defaults to {@code false}, meaning that the whole result set is fetched to memory eagerly.
+     * <p>
+     * Only applicable to SqlFieldsQuery
+     */
+    boolean lazy() default false;
+
+    /**
+     * Sets whether this query should be executed on local node only.
+     */
+    boolean local() default false;
+
+    /**
+     * Sets partitions for a query. The query will be executed only on nodes which are primary for specified
+     * partitions.
+     * <p>
+     * Note what passed array'll be sorted in place for performance reasons, if it wasn't sorted yet.
+     * <p>
+     * Only applicable to SqlFieldsQuery and SqlQuery
+     */
+    int[] parts() default {};
+
+    /**
+     * Specify whether the annotated method must provide a non null {@link DynamicQueryConfig} parameter with a non
+     * empty value (query string) or {@link DynamicQueryConfig#textQuery()} == true.
+     * <p>
+     * Please, note that  {@link DynamicQueryConfig#textQuery()} annotation parameters will be ignored in favor of those
+     * defined in {@link DynamicQueryConfig} parameter if present (runtime ignite query tuning).
+     */
+    boolean dynamicQuery() default false;
+
+    /**
+     * Sets limit to response records count for TextQuery. If 0 or less, considered to be no limit.
+     */
+    int limit() default 0;
 }
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
index 4a3703e..e990cba 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/RepositoryConfig.java
@@ -24,8 +24,16 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.ignite.Ignite;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+
 /**
  * The annotation can be used to pass Ignite specific parameters to a bound repository.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
@@ -33,7 +41,37 @@
 @Inherited
 public @interface RepositoryConfig {
     /**
+     * Cache name string.
+     *
      * @return A name of a distributed Apache Ignite cache an annotated repository will be mapped to.
      */
     String cacheName() default "";
+
+    /**
+     * Name of the Spring Bean that must provide {@link Ignite} or {@link IgniteClient} instance for accessing the
+     * Ignite cluster.
+     */
+    String igniteInstance() default "igniteInstance";
+
+    /**
+     * Name of the Spring Bean that must provide {@link IgniteConfiguration} or {@link ClientConfiguration} that is used
+     * for instantination of Ignite node or Ignite thin client respectively for accessing the Ignite cluster.
+     */
+    String igniteCfg() default "igniteCfg";
+
+    /**
+     * Ignite spring cfg path string. Default "igniteSpringCfgPath".
+     *
+     * @return A path to Ignite's Spring XML configuration spring bean name
+     */
+    String igniteSpringCfgPath() default "igniteSpringCfgPath";
+
+    /**
+     * Auto create cache. Default false to enforce control over cache creation and to avoid cache creation by mistake
+     * <p>
+     * Tells to Ignite Repository factory wether cache should be auto created if not exists.
+     *
+     * @return the boolean
+     */
+    boolean autoCreateCache() default false;
 }
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
index c7f473b..ab142ae 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/config/package-info.java
@@ -19,5 +19,4 @@
  * <!-- Package description. -->
  * Package includes Spring Data integration related configuration files.
  */
-
 package org.apache.ignite.springdata.repository.config;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
index 773abea..d3dceb6 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/package-info.java
@@ -19,5 +19,4 @@
  * <!-- Package description. -->
  * Package contains Apache Ignite Spring Data integration.
  */
-
 package org.apache.ignite.springdata.repository;
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
similarity index 97%
rename from modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
index fa5043d..55e8428 100644
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/DeclaredQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/DeclaredQuery.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata20.repository.query;
+package org.apache.ignite.springdata.repository.query;
 
 import java.util.List;
 import org.jetbrains.annotations.Nullable;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
similarity index 97%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
index 6f697a2..3359a24 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/EmptyDeclaredQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/EmptyDeclaredQuery.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
 
 import java.util.Collections;
 import java.util.List;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
similarity index 98%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
index 9279da7..e296f84 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/ExpressionBasedStringQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/ExpressionBasedStringQuery.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
 
 import java.util.regex.Pattern;
 import org.springframework.data.repository.core.EntityMetadata;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
index f630ca0..37bd3ce 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQuery.java
@@ -17,8 +17,13 @@
 
 package org.apache.ignite.springdata.repository.query;
 
+import org.apache.ignite.internal.util.typedef.internal.S;
+
 /**
  * Ignite query helper class. For internal use only.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
 public class IgniteQuery {
     /** */
@@ -33,23 +38,47 @@
         NONE
     }
 
-    /** Sql query text string. */
-    private final String sql;
+    /**
+     * Query text string.
+     */
+    private final String qrySql;
 
-    /** */
+    /**
+     * Whether this is a SQL fields query
+     */
     private final boolean isFieldQuery;
 
-    /** Type of option. */
+    /**
+     * Whether this is Text query
+     */
+    private final boolean isTextQuery;
+
+    /**
+     * Whether was autogenerated (by method name)
+     */
+    private final boolean isAutogenerated;
+
+    /**
+     * Type of option.
+     */
     private final Option option;
 
     /**
-     * @param sql Sql.
-     * @param isFieldQuery Is field query.
-     * @param option Option.
+     * @param qrySql          the query string.
+     * @param isFieldQuery    Is field query.
+     * @param isTextQuery     Is a TextQuery
+     * @param isAutogenerated query was autogenerated
+     * @param option          Option.
      */
-    public IgniteQuery(String sql, boolean isFieldQuery, Option option) {
-        this.sql = sql;
+    public IgniteQuery(String qrySql,
+        boolean isFieldQuery,
+        boolean isTextQuery,
+        boolean isAutogenerated,
+        Option option) {
+        this.qrySql = qrySql;
         this.isFieldQuery = isFieldQuery;
+        this.isTextQuery = isTextQuery;
+        this.isAutogenerated = isAutogenerated;
         this.option = option;
     }
 
@@ -58,8 +87,8 @@
      *
      * @return SQL query text string.
      */
-    public String sql() {
-        return sql;
+    public String qryStr() {
+        return qrySql;
     }
 
     /**
@@ -72,6 +101,24 @@
     }
 
     /**
+     * Returns {@code true} if it's Ignite Text query, {@code false} otherwise.
+     *
+     * @return {@code true} if it's Ignite Text query, {@code false} otherwise.
+     */
+    public boolean isTextQuery() {
+        return isTextQuery;
+    }
+
+    /**
+     * Returns {@code true} if it's autogenerated, {@code false} otherwise.
+     *
+     * @return {@code true} if it's autogenerated, {@code false} otherwise.
+     */
+    public boolean isAutogenerated() {
+        return isAutogenerated;
+    }
+
+    /**
      * Advanced querying option.
      *
      * @return querying option.
@@ -79,5 +126,9 @@
     public Option options() {
         return option;
     }
-}
 
+    /** */
+    @Override public String toString() {
+        return S.toString(IgniteQuery.class, this);
+    }
+}
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
index e1f3f2f..6bf02bc 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteQueryGenerator.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.springdata.repository.query;
 
 import java.lang.reflect.Method;
-import org.jetbrains.annotations.NotNull;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.mapping.PropertyPath;
@@ -31,12 +30,17 @@
  * Ignite query generator for Spring Data framework.
  */
 public class IgniteQueryGenerator {
+    /** */
+    private IgniteQueryGenerator() {
+        // No-op.
+    }
 
     /**
-     * @param mtd Method.
+     * @param mtd      Method.
      * @param metadata Metadata.
+     * @return Generated ignite query.
      */
-    @NotNull public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
+    public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
         PartTree parts;
 
         try {
@@ -46,20 +50,26 @@
             parts = new PartTree(mtd.getName(), metadata.getIdType());
         }
 
+        boolean isCountOrFieldQuery = parts.isCountProjection();
+
         StringBuilder sql = new StringBuilder();
 
-        if (parts.isDelete())
-            throw new UnsupportedOperationException("DELETE clause is not supported now.");
+        if (parts.isDelete()) {
+            sql.append("DELETE ");
+
+            // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
+            isCountOrFieldQuery = true;
+        }
         else {
             sql.append("SELECT ");
 
             if (parts.isDistinct())
                 throw new UnsupportedOperationException("DISTINCT clause in not supported.");
 
-            if (parts.isCountProjection())
+            if (isCountOrFieldQuery)
                 sql.append("COUNT(1) ");
             else
-                sql.append(" * ");
+                sql.append("* ");
         }
 
         sql.append("FROM ").append(metadata.getDomainType().getSimpleName());
@@ -69,6 +79,7 @@
 
             for (PartTree.OrPart orPart : parts) {
                 sql.append("(");
+
                 for (Part part : orPart) {
                     handleQueryPart(sql, part, metadata.getDomainType());
                     sql.append(" AND ");
@@ -89,17 +100,18 @@
             sql.append(parts.getMaxResults().intValue());
         }
 
-        return new IgniteQuery(sql.toString(), parts.isCountProjection(), getOptions(mtd));
+        return new IgniteQuery(sql.toString(), isCountOrFieldQuery, false, true, getOptions(mtd));
     }
 
     /**
      * Add a dynamic part of query for the sorting support.
      *
-     * @param sql SQL text string.
+     * @param sql  SQL text string.
      * @param sort Sort method.
+     * @return Sorting criteria in StringBuilder.
      */
     public static StringBuilder addSorting(StringBuilder sql, Sort sort) {
-        if (sort != null) {
+        if (sort != null && sort != Sort.unsorted()) {
             sql.append(" ORDER BY ");
 
             for (Sort.Order order : sort) {
@@ -107,6 +119,7 @@
 
                 if (order.getNullHandling() != Sort.NullHandling.NATIVE) {
                     sql.append(" ").append("NULL ");
+
                     switch (order.getNullHandling()) {
                         case NULLS_FIRST:
                             sql.append("FIRST");
@@ -114,6 +127,7 @@
                         case NULLS_LAST:
                             sql.append("LAST");
                             break;
+                        default:
                     }
                 }
                 sql.append(", ");
@@ -128,13 +142,13 @@
     /**
      * Add a dynamic part of a query for the pagination support.
      *
-     * @param sql Builder instance.
+     * @param sql      Builder instance.
      * @param pageable Pageable instance.
      * @return Builder instance.
      */
     public static StringBuilder addPaging(StringBuilder sql, Pageable pageable) {
-        if (pageable.getSort() != null)
-            addSorting(sql, pageable.getSort());
+
+        addSorting(sql, pageable.getSort());
 
         sql.append(" LIMIT ").append(pageable.getPageSize()).append(" OFFSET ").append(pageable.getOffset());
 
@@ -151,7 +165,6 @@
         IgniteQuery.Option option = IgniteQuery.Option.NONE;
 
         Class<?>[] types = mtd.getParameterTypes();
-
         if (types.length > 0) {
             Class<?> type = types[types.length - 1];
 
@@ -163,6 +176,7 @@
 
         for (int i = 0; i < types.length - 1; i++) {
             Class<?> tp = types[i];
+
             if (tp == Sort.class || tp == Pageable.class)
                 throw new AssertionError("Sort and Pageable parameters are allowed only in the last position");
         }
@@ -183,7 +197,7 @@
     }
 
     /**
-     * Transform part to sql expression
+     * Transform part to qryStr expression
      */
     private static void handleQueryPart(StringBuilder sql, Part part, Class<?> domainType) {
         sql.append("(");
@@ -224,15 +238,13 @@
             case TRUE:
                 sql.append(" = TRUE");
                 break;
+            //TODO: review this legacy code, LIKE should be -> LIKE ?
+            case LIKE:
             case CONTAINING:
                 sql.append(" LIKE '%' || ? || '%'");
                 break;
             case NOT_CONTAINING:
-                sql.append(" NOT LIKE '%' || ? || '%'");
-                break;
-            case LIKE:
-                sql.append(" LIKE '%' || ? || '%'");
-                break;
+                //TODO: review this legacy code, NOT_LIKE should be -> NOT LIKE ?
             case NOT_LIKE:
                 sql.append(" NOT LIKE '%' || ? || '%'");
                 break;
@@ -262,4 +274,3 @@
         sql.append(")");
     }
 }
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
index 79ce6c0..6736388 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/IgniteRepositoryQuery.java
@@ -17,39 +17,151 @@
 
 package org.apache.ignite.springdata.repository.query;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.util.AbstractCollection;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.cache.Cache;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.reflect.FieldUtils;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
 import org.apache.ignite.cache.query.Query;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cache.query.TextQuery;
 import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
-import org.jetbrains.annotations.NotNull;
+import org.apache.ignite.springdata.proxy.IgniteClientCacheProxy;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.springdata.repository.config.DynamicQueryConfig;
+import org.apache.ignite.springdata.repository.query.StringQuery.ParameterBinding;
 import org.jetbrains.annotations.Nullable;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Slice;
 import org.springframework.data.domain.SliceImpl;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.projection.ProjectionFactory;
 import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.query.Parameter;
+import org.springframework.data.repository.query.Parameters;
 import org.springframework.data.repository.query.QueryMethod;
+import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
 import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ParserContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.util.StringUtils;
 
-import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addPaging;
-import static org.apache.ignite.springdata.repository.query.IgniteQueryGenerator.addSorting;
+import static org.apache.ignite.internal.processors.query.QueryUtils.KEY_FIELD_NAME;
+import static org.apache.ignite.internal.processors.query.QueryUtils.VAL_FIELD_NAME;
+import static org.apache.ignite.springdata.repository.support.IgniteRepositoryFactory.isFieldQuery;
 
 /**
- * Ignite SQL query implementation.
+ * Ignite query implementation.
+ * <p>
+ * <p>
+ * Features:
+ * <ol>
+ * <li> Supports query tuning parameters</li>
+ * <li> Supports projections</li>
+ * <li> Supports Page and Stream responses</li>
+ * <li> Supports SqlFieldsQuery resultset transformation into the domain entity</li>
+ * <li> Supports named parameters (:myParam) into SQL queries, declared using @Param("myParam") annotation</li>
+ * <li> Supports advanced parameter binding and SpEL expressions into SQL queries
+ * <ol>
+ * <li><b>Template variables</b>:
+ * <ol>
+ * <li>{@code #entityName} - the simple class name of the domain entity</li>
+ * </ol>
+ * </li>
+ * <li><b>Method parameter expressions</b>: Parameters are exposed for indexed access ([0] is the first query method's
+ * param) or via the name declared using @Param. The actual SpEL expression binding is triggered by '?#'. Example:
+ * ?#{[0]} or ?#{#myParamName}</li>
+ * <li><b>Advanced SpEL expressions</b>: While advanced parameter binding is a very useful feature, the real power of
+ * SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components
+ * through SpEL EvaluationContext extension model.</li>
+ * </ol>
+ * Examples:
+ * <pre>
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
+ * User searchUserByEmail({@code @Param}("email") String email);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where country = ?#{[0]} and city = ?#{[1]}")
+ * List<User> searchUsersByCity({@code @Param}("country") String country, {@code @Param}("city") String city,
+ * Pageable pageable);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = ?")
+ * User searchUserByEmail(String email);
+ *
+ * {@code @Query}(value = "SELECT * from #{#entityName} where lucene = ?#{
+ * luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder.match('city',#city)).build()}")
+ * List<User> searchUsersByCity({@code @Param}("city") String city, Pageable pageable);
+ * </pre>
+ * </li>
+ * <li> Supports SpEL expressions into Text queries ({@link TextQuery}). Examples:
+ * <pre>
+ * {@code @Query}(textQuery = true, value = "email: #{#email}")
+ * User searchUserByEmail({@code @Param}("email") String email);
+ *
+ * {@code @Query}(textQuery = true, value = "#{#textToSearch}")
+ * List<User> searchUsersByText({@code @Param}("textToSearch") String text, Pageable pageable);
+ *
+ * {@code @Query}(textQuery = true, value = "#{[0]}")
+ * List<User> searchUsersByText(String textToSearch, Pageable pageable);
+ *
+ * {@code @Query}(textQuery = true, value = "#{luceneQueryBuilder.search().refresh(true).filter(luceneQueryBuilder
+ * .match('city', #city)).build()}")
+ * List<User> searchUserByCity({@code @Param}("city") String city, Pageable pageable);
+ * </pre>
+ * </li>
+ * <li> Supports dynamic query and tuning at runtime by using {@link DynamicQueryConfig} method parameter. Examples:
+ * <pre>
+ * {@code @Query}(value = "SELECT * from #{#entityName} where email = :email")
+ * User searchUserByEmailWithQueryTuning({@code @Param}("email") String email, {@code @Param}("ignoredUsedAsQueryTuning") DynamicQueryConfig config);
+ *
+ * {@code @Query}(dynamicQuery = true)
+ * List<User> searchUsersByCityWithDynamicQuery({@code @Param}("country") String country, {@code @Param}("city") String city,
+ * {@code @Param}("ignoredUsedAsDynamicQueryAndTuning") DynamicQueryConfig config, Pageable pageable);
+ *
+ * ...
+ * DynamicQueryConfig onlyTunning = new DynamicQueryConfig().setCollocated(true);
+ * repo.searchUserByEmailWithQueryTuning("user@mail.com", onlyTunning);
+ *
+ * DynamicQueryConfig withDynamicQuery = new DynamicQueryConfig().value("SELECT * from #{#entityName} where country = ?#{[0] and city = ?#{[1]}").setForceFieldsQuery(true).setLazy(true).setCollocated(true);
+ * repo.searchUsersByCityWithDynamicQuery("Spain", "Madrid", withDynamicQuery, new PageRequest(0, 100));
+ *
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
-@SuppressWarnings({"unchecked", "rawtypes"})
+@SuppressWarnings("unchecked")
 public class IgniteRepositoryQuery implements RepositoryQuery {
-    /** Defines the way how to process query result */
+    /**
+     * Defines the way how to process query result
+     */
     private enum ReturnStrategy {
         /** Need to return only one value. */
         ONE_VALUE,
@@ -69,60 +181,181 @@
         /** Need to return slice */
         SLICE_OF_VALUES,
 
-        /** Slice of cache entries. */
+        /** Slice of cache entries */
         SLICE_OF_CACHE_ENTRIES,
 
-        /** Slice of lists. */
-        SLICE_OF_LISTS
+        /** Slice of lists */
+        SLICE_OF_LISTS,
+
+        /** Need to return Page of values */
+        PAGE_OF_VALUES,
+
+        /** Need to return stream of values */
+        STREAM_OF_VALUES,
     }
 
-    /** Type. */
+    /** */
     private final Class<?> type;
 
-    /** Sql. */
-    private final IgniteQuery qry;
+    /** Domain entitiy field descriptors mapped to their names in lower case. */
+    private final Map<String, Field> domainEntitiyFields;
 
-    /** Cache. */
+    /** */
+    private final IgniteQuery staticQuery;
+
+    /** */
     private final IgniteCacheProxy<?, ?> cache;
 
-    /** Method. */
+    /** */
     private final Method mtd;
 
-    /** Metadata. */
+    /** */
     private final RepositoryMetadata metadata;
 
-    /** Factory. */
+    /** */
     private final ProjectionFactory factory;
 
-    /** Return strategy. */
-    private final ReturnStrategy returnStgy;
+    /** */
+    private final ReturnStrategy staticReturnStgy;
+
+    /** Detect if returned data from method is projected */
+    private final boolean hasProjection;
+
+    /** Whether projection is dynamic (provided as method parameter) */
+    private final boolean hasDynamicProjection;
+
+    /** Dynamic projection parameter index */
+    private final int dynamicProjectionIndex;
+
+    /** Dynamic query configuration */
+    private final int dynamicQueryConfigurationIndex;
+
+    /** The return query method */
+    private final QueryMethod qMethod;
+
+    /** The return domain class of QueryMethod */
+    private final Class<?> returnedDomainClass;
+
+    /** */
+    private final SpelExpressionParser expressionParser;
+
+    /** Could provide ExtensionAwareQueryMethodEvaluationContextProvider */
+    private final QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider;
+
+    /** Static query configuration. */
+    private final DynamicQueryConfig staticQueryConfiguration;
 
     /**
-     * @param metadata Metadata.
-     * @param qry Query.
-     * @param mtd Method.
-     * @param factory Factory.
-     * @param cache Cache.
+     * Instantiates a new Ignite repository query.
+     *
+     * @param metadata                             Metadata.
+     * @param staticQuery                          Query.
+     * @param mtd                                  Method.
+     * @param factory                              Factory.
+     * @param cache                                Cache.
+     * @param staticQueryConfiguration             the query configuration
+     * @param queryMethodEvaluationContextProvider the query method evaluation context provider
      */
-    public IgniteRepositoryQuery(RepositoryMetadata metadata, IgniteQuery qry,
-        Method mtd, ProjectionFactory factory, IgniteCacheProxy<?, ?> cache) {
-        type = metadata.getDomainType();
-        this.qry = qry;
-        this.cache = cache;
+    public IgniteRepositoryQuery(
+        RepositoryMetadata metadata,
+        @Nullable IgniteQuery staticQuery,
+        Method mtd,
+        ProjectionFactory factory,
+        IgniteCacheProxy<? ,?> cache,
+        @Nullable DynamicQueryConfig staticQueryConfiguration,
+        QueryMethodEvaluationContextProvider queryMethodEvaluationContextProvider) {
         this.metadata = metadata;
         this.mtd = mtd;
         this.factory = factory;
+        type = metadata.getDomainType();
 
-        returnStgy = calcReturnType(mtd, qry.isFieldQuery());
+        domainEntitiyFields = Arrays.stream(type.getDeclaredFields())
+            .collect(Collectors.toMap(field -> field.getName().toLowerCase(), field -> field));
+
+        this.cache = cache;
+
+        this.staticQueryConfiguration = staticQueryConfiguration;
+        this.staticQuery = staticQuery;
+
+        if (this.staticQuery != null)
+            staticReturnStgy = calcReturnType(mtd, this.staticQuery.isFieldQuery());
+        else
+            staticReturnStgy = null;
+
+        expressionParser = new SpelExpressionParser();
+        this.queryMethodEvaluationContextProvider = queryMethodEvaluationContextProvider;
+
+        qMethod = getQueryMethod();
+
+        // control projection
+        hasDynamicProjection = getQueryMethod().getParameters().hasDynamicProjection();
+        hasProjection = hasDynamicProjection || getQueryMethod().getResultProcessor().getReturnedType()
+            .isProjecting();
+
+        dynamicProjectionIndex = qMethod.getParameters().getDynamicProjectionIndex();
+
+        returnedDomainClass = getQueryMethod().getReturnedObjectType();
+
+        dynamicQueryConfigurationIndex = getDynamicQueryConfigurationIndex(qMethod);
+
+        // ensure dynamic query configuration param exists if dynamicQuery = true
+        if (dynamicQueryConfigurationIndex == -1 && this.staticQuery == null) {
+            throw new IllegalStateException(
+                "When passing dynamicQuery = true via org.apache.ignite.springdata.repository.config.Query "
+                    + "annotation, you must provide a non null method parameter of type DynamicQueryConfig");
+        }
     }
 
-    /** {@inheritDoc} */
-    @Override public Object execute(Object[] prmtrs) {
-        Query qry = prepareQuery(prmtrs);
+    /**
+     * {@inheritDoc} @param values the values
+     *
+     * @return the object
+     */
+    @Override public Object execute(Object[] values) {
+        Object[] parameters = values;
 
-        try (QueryCursor qryCursor = cache.query(qry)) {
-            return transformQueryCursor(prmtrs, qryCursor);
+        // config via Query annotation (dynamicQuery = false)
+        DynamicQueryConfig config = staticQueryConfiguration;
+
+        // or condition to allow query tunning
+        if (config == null || dynamicQueryConfigurationIndex != -1) {
+            DynamicQueryConfig newConfig = (DynamicQueryConfig)values[dynamicQueryConfigurationIndex];
+            parameters = ArrayUtils.removeElement(parameters, dynamicQueryConfigurationIndex);
+            if (newConfig != null) {
+                // upset query configuration
+                config = newConfig;
+            }
         }
+        // query configuration is required, via Query annotation or per parameter (within provided values param)
+        if (config == null) {
+            throw new IllegalStateException(
+                "Unable to execute query. When passing dynamicQuery = true via org.apache.ignite.springdata"
+                    + ".repository.config.Query annotation, you must provide a non null method parameter of type "
+                    + "DynamicQueryConfig");
+        }
+
+        IgniteQuery qry = getQuery(config);
+
+        ReturnStrategy returnStgy = getReturnStgy(qry);
+
+        Query iQry = prepareQuery(qry, config, returnStgy, parameters);
+
+        QueryCursor qryCursor;
+
+        try {
+            qryCursor = cache.query(iQry);
+        }
+        catch (IllegalArgumentException e) {
+            if (cache instanceof IgniteClientCacheProxy) {
+                throw new IllegalStateException(String.format("Query of type %s is not supported by thin client." +
+                    " Check %s#%s method configuration or use Ignite node instance to connect to the Ignite cluster.",
+                    iQry.getClass().getSimpleName(), mtd.getDeclaringClass().getName(), mtd.getName()), e);
+            }
+
+            throw e;
+        }
+
+        return transformQueryCursor(qry, returnStgy, parameters, qryCursor);
     }
 
     /** {@inheritDoc} */
@@ -130,6 +363,29 @@
         return new QueryMethod(mtd, metadata, factory);
     }
 
+    private <T extends Parameter> int getDynamicQueryConfigurationIndex(QueryMethod method) {
+        Iterator<T> it = (Iterator<T>)method.getParameters().iterator();
+        int i = 0;
+        boolean found = false;
+        int index = -1;
+        while (it.hasNext()) {
+            T parameter = it.next();
+
+            if (DynamicQueryConfig.class.isAssignableFrom(parameter.getType())) {
+                if (found) {
+                    throw new IllegalStateException("Invalid '" + method.getName() + "' repository method signature. "
+                        + "Only ONE DynamicQueryConfig parameter is allowed");
+                }
+
+                found = true;
+                index = i;
+            }
+
+            i++;
+        }
+        return index;
+    }
+
     /**
      * @param mtd Method.
      * @param isFieldQry Is field query.
@@ -138,39 +394,46 @@
     private ReturnStrategy calcReturnType(Method mtd, boolean isFieldQry) {
         Class<?> returnType = mtd.getReturnType();
 
-        if (returnType.isAssignableFrom(ArrayList.class)) {
-            if (isFieldQry) {
-                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
-                    return ReturnStrategy.LIST_OF_LISTS;
-            }
-            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
-                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
-
-            return ReturnStrategy.LIST_OF_VALUES;
-        }
-        else if (returnType == Slice.class) {
+        if (returnType == Slice.class) {
             if (isFieldQry) {
                 if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
                     return ReturnStrategy.SLICE_OF_LISTS;
             }
             else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
                 return ReturnStrategy.SLICE_OF_CACHE_ENTRIES;
-
             return ReturnStrategy.SLICE_OF_VALUES;
         }
+        else if (returnType == Page.class)
+            return ReturnStrategy.PAGE_OF_VALUES;
+        else if (returnType == Stream.class)
+            return ReturnStrategy.STREAM_OF_VALUES;
         else if (Cache.Entry.class.isAssignableFrom(returnType))
             return ReturnStrategy.CACHE_ENTRY;
+        else if (Iterable.class.isAssignableFrom(returnType)) {
+            if (isFieldQry) {
+                if (hasAssignableGenericReturnTypeFrom(ArrayList.class, mtd))
+                    return ReturnStrategy.LIST_OF_LISTS;
+            }
+            else if (hasAssignableGenericReturnTypeFrom(Cache.Entry.class, mtd))
+                return ReturnStrategy.LIST_OF_CACHE_ENTRIES;
+            return ReturnStrategy.LIST_OF_VALUES;
+        }
         else
             return ReturnStrategy.ONE_VALUE;
     }
 
     /**
-     * @param cls Class 1.
+     * @param cls Class.
      * @param mtd Method.
      * @return if {@code mtd} return type is assignable from {@code cls}
      */
     private boolean hasAssignableGenericReturnTypeFrom(Class<?> cls, Method mtd) {
-        Type[] actualTypeArguments = ((ParameterizedType)mtd.getGenericReturnType()).getActualTypeArguments();
+        Type genericReturnType = mtd.getGenericReturnType();
+
+        if (!(genericReturnType instanceof ParameterizedType))
+            return false;
+
+        Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
 
         if (actualTypeArguments.length == 0)
             return false;
@@ -193,91 +456,185 @@
     }
 
     /**
-     * @param prmtrs Prmtrs.
+     * When select fields by query H2 returns Timestamp for types java.util.Date and java.qryStr.Timestamp
+     *
+     * @see org.apache.ignite.internal.processors.query.h2.H2DatabaseType map.put(Timestamp.class, TIMESTAMP)
+     * map.put(java.util.Date.class, TIMESTAMP) map.put(java.qryStr.Date.class, DATE)
+     */
+    private static <T> T fixExpectedType(final Object object, final Class<T> expected) {
+        if (expected != null && object instanceof java.sql.Timestamp && expected.equals(java.util.Date.class))
+            return (T)new java.util.Date(((java.sql.Timestamp)object).getTime());
+
+        return (T)object;
+    }
+
+    /**
+     * @param cfg Config.
+     */
+    private IgniteQuery getQuery(@Nullable DynamicQueryConfig cfg) {
+        if (staticQuery != null)
+            return staticQuery;
+
+        if (cfg != null && (StringUtils.hasText(cfg.value()) || cfg.textQuery())) {
+            return new IgniteQuery(cfg.value(),
+                !cfg.textQuery() && (isFieldQuery(cfg.value()) || cfg.forceFieldsQuery()), cfg.textQuery(),
+                false, IgniteQueryGenerator.getOptions(mtd));
+        }
+
+        throw new IllegalStateException("Unable to obtain a valid query. When passing dynamicQuery = true via org"
+            + ".apache.ignite.springdata.repository.config.Query annotation, you must"
+            + " provide a non null method parameter of type DynamicQueryConfig with a "
+            + "non empty value (query string) or textQuery = true");
+    }
+
+    /**
+     * @param qry Query.
+     */
+    private ReturnStrategy getReturnStgy(IgniteQuery qry) {
+        if (staticReturnStgy != null)
+            return staticReturnStgy;
+
+        if (qry != null)
+            return calcReturnType(mtd, qry.isFieldQuery());
+
+        throw new IllegalStateException("Unable to obtain a valid return strategy. When passing dynamicQuery = true "
+            + "via org.apache.ignite.springdata.repository.config.Query annotation, "
+            + "you must provide a non null method parameter of type "
+            + "DynamicQueryConfig with a non empty value (query string) or textQuery "
+            + "= true");
+    }
+
+    /**
+     * @param cls Class.
+     */
+    private static boolean isPrimitiveOrWrapper(Class<?> cls) {
+        return cls.isPrimitive() ||
+            Boolean.class.equals(cls) ||
+            Byte.class.equals(cls) ||
+            Character.class.equals(cls) ||
+            Short.class.equals(cls) ||
+            Integer.class.equals(cls) ||
+            Long.class.equals(cls) ||
+            Float.class.equals(cls) ||
+            Double.class.equals(cls) ||
+            Void.class.equals(cls) ||
+            String.class.equals(cls) ||
+            UUID.class.equals(cls);
+    }
+
+    /**
+     * @param prmtrs    Prmtrs.
      * @param qryCursor Query cursor.
      * @return Query cursor or slice
      */
-    @Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
+    @Nullable
+    private Object transformQueryCursor(IgniteQuery qry,
+        ReturnStrategy returnStgy,
+        Object[] prmtrs,
+        QueryCursor qryCursor) {
+        final Class<?> returnClass;
+
+        if (hasProjection) {
+            if (hasDynamicProjection)
+                returnClass = (Class<?>)prmtrs[dynamicProjectionIndex];
+            else
+                returnClass = returnedDomainClass;
+        }
+        else
+            returnClass = returnedDomainClass;
+
         if (qry.isFieldQuery()) {
-            Iterable<List> qryIter = (Iterable<List>)qryCursor;
+            // take control over single primite result from queries, i.e. DELETE, SELECT COUNT, UPDATE ...
+            boolean singlePrimitiveResult = isPrimitiveOrWrapper(returnClass);
+
+            FieldsQueryCursor<?> fieldQryCur = (FieldsQueryCursor<?>)qryCursor;
+
+            Function<List<?>, ?> cWrapperTransformFunction = null;
+
+            if (type.equals(returnClass))
+                cWrapperTransformFunction = row -> rowToEntity(row, fieldQryCur);
+            else {
+                if (hasProjection || singlePrimitiveResult) {
+                    if (singlePrimitiveResult)
+                        cWrapperTransformFunction = row -> row.get(0);
+                    else {
+                        // Map row -> projection class
+                        cWrapperTransformFunction = row -> factory
+                            .createProjection(returnClass, rowToMap(row, fieldQryCur));
+                    }
+                }
+                else
+                    cWrapperTransformFunction = row -> rowToMap(row, fieldQryCur);
+            }
+
+            QueryCursorWrapper<?, ?> cWrapper = new QueryCursorWrapper<>((QueryCursor<List<?>>)qryCursor,
+                cWrapperTransformFunction);
 
             switch (returnStgy) {
+                case PAGE_OF_VALUES:
+                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
                 case LIST_OF_VALUES:
-                    List list = new ArrayList<>();
-
-                    for (List entry : qryIter)
-                        list.add(entry.get(0));
-
-                    return list;
-
+                    return cWrapper.getAll();
+                case STREAM_OF_VALUES:
+                    return cWrapper.stream();
                 case ONE_VALUE:
-                    Iterator<List> iter = qryIter.iterator();
-
-                    if (iter.hasNext())
-                        return iter.next().get(0);
-
+                    Iterator<?> iter = cWrapper.iterator();
+                    if (iter.hasNext()) {
+                        Object resp = iter.next();
+                        U.closeQuiet(cWrapper);
+                        return resp;
+                    }
                     return null;
-
                 case SLICE_OF_VALUES:
-                    List content = new ArrayList<>();
-
-                    for (List entry : qryIter)
-                        content.add(entry.get(0));
-
-                    return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
-
+                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
                 case SLICE_OF_LISTS:
                     return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-
                 case LIST_OF_LISTS:
                     return qryCursor.getAll();
-
                 default:
                     throw new IllegalStateException();
             }
         }
         else {
-            Iterable<Cache.Entry<?, ?>> qryIter = (Iterable<Cache.Entry<?, ?>>)qryCursor;
+            Function<Cache.Entry<?, ?>, ?> cWrapperTransformFunction;
+
+            if (hasProjection && !type.equals(returnClass))
+                cWrapperTransformFunction = row -> factory.createProjection(returnClass, row.getValue());
+            else
+                cWrapperTransformFunction = Cache.Entry::getValue;
+
+            QueryCursorWrapper<Cache.Entry<?, ?>, ?> cWrapper = new QueryCursorWrapper<>(
+                (QueryCursor<Cache.Entry<?, ?>>)qryCursor, cWrapperTransformFunction);
 
             switch (returnStgy) {
+                case PAGE_OF_VALUES:
+                    return new PageImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], 0);
                 case LIST_OF_VALUES:
-                    List list = new ArrayList<>();
-
-                    for (Cache.Entry<?, ?> entry : qryIter)
-                        list.add(entry.getValue());
-
-                    return list;
-
+                    return cWrapper.getAll();
+                case STREAM_OF_VALUES:
+                    return cWrapper.stream();
                 case ONE_VALUE:
-                    Iterator<Cache.Entry<?, ?>> iter1 = qryIter.iterator();
-
-                    if (iter1.hasNext())
-                        return iter1.next().getValue();
-
+                    Iterator<?> iter1 = cWrapper.iterator();
+                    if (iter1.hasNext()) {
+                        Object resp = iter1.next();
+                        U.closeQuiet(cWrapper);
+                        return resp;
+                    }
                     return null;
-
                 case CACHE_ENTRY:
-                    Iterator<Cache.Entry<?, ?>> iter2 = qryIter.iterator();
-
-                    if (iter2.hasNext())
-                        return iter2.next();
-
+                    Iterator<?> iter2 = qryCursor.iterator();
+                    if (iter2.hasNext()) {
+                        Object resp2 = iter2.next();
+                        U.closeQuiet(qryCursor);
+                        return resp2;
+                    }
                     return null;
-
                 case SLICE_OF_VALUES:
-                    List content = new ArrayList<>();
-
-                    for (Cache.Entry<?, ?> entry : qryIter)
-                        content.add(entry.getValue());
-
-                    return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
-
+                    return new SliceImpl(cWrapper.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
                 case SLICE_OF_CACHE_ENTRIES:
                     return new SliceImpl(qryCursor.getAll(), (Pageable)prmtrs[prmtrs.length - 1], true);
-
                 case LIST_OF_CACHE_ENTRIES:
                     return qryCursor.getAll();
-
                 default:
                     throw new IllegalStateException();
             }
@@ -285,41 +642,329 @@
     }
 
     /**
-     * @param prmtrs Prmtrs.
+     * Extract bindable values
+     *
+     * @param values            values invoking query method
+     * @param queryMethodParams query method parameter definitions
+     * @param queryBindings     All parameters found on query string that need to be binded
+     * @return new list of parameters
+     */
+    private Object[] extractBindableValues(Object[] values,
+        Parameters<?, ?> queryMethodParams,
+        List<ParameterBinding> queryBindings) {
+        // no binding params then exit
+        if (queryBindings.isEmpty())
+            return values;
+
+        Object[] newValues = new Object[queryBindings.size()];
+
+        // map bindable parameters from query method: (index/name) - index
+        HashMap<String, Integer> methodParams = new HashMap<>();
+
+        // create an evaluation context for custom query
+        EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
+            .getEvaluationContext(queryMethodParams, values);
+
+        // By default queryEvalContext:
+        // - make accesible query method parameters by index:
+        // @Query("select u from User u where u.age = ?#{[0]}")
+        // List<User> findUsersByAge(int age);
+        // - make accesible query method parameters by name:
+        // @Query("select u from User u where u.firstname = ?#{#customer.firstname}")
+        // List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
+
+        // query method param's index by name and position
+        queryMethodParams.getBindableParameters().forEach(p -> {
+            if (p.isNamedParameter()) {
+                // map by name (annotated by @Param)
+                methodParams.put(p.getName().get(), p.getIndex());
+            }
+            // map by position
+            methodParams.put(String.valueOf(p.getIndex()), p.getIndex());
+        });
+
+        // process all parameters on query and extract new values to bind
+        for (int i = 0; i < queryBindings.size(); i++) {
+            ParameterBinding p = queryBindings.get(i);
+
+            if (p.isExpression()) {
+                // Evaluate SpEl expressions (synthetic parameter value) , example ?#{#customer.firstname}
+                newValues[i] = expressionParser.parseExpression(p.getExpression()).getValue(queryEvalContext);
+            }
+            else {
+                // Extract parameter value by name or position respectively from invoking values
+                newValues[i] = values[methodParams.get(
+                    p.getName() != null ? p.getName() : String.valueOf(p.getRequiredPosition() - 1))];
+            }
+        }
+
+        return newValues;
+    }
+
+    /**
+     * @param qry        Query.
+     * @param config     Config.
+     * @param returnStgy Return stgy.
+     * @param values     Values.
      * @return prepared query for execution
      */
-    @SuppressWarnings("deprecation")
-    @NotNull private Query prepareQuery(Object[] prmtrs) {
-        Object[] parameters = prmtrs;
-        String sql = qry.sql();
+    private Query prepareQuery(IgniteQuery qry, DynamicQueryConfig config, ReturnStrategy returnStgy, Object[] values) {
+        Object[] parameters = values;
 
-        switch (qry.options()) {
-            case SORTING:
-                sql = addSorting(new StringBuilder(sql), (Sort)parameters[parameters.length - 1]).toString();
-                parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+        String queryString = qry.qryStr();
 
-                break;
+        Query query;
 
-            case PAGINATION:
-                sql = addPaging(new StringBuilder(sql), (Pageable)parameters[parameters.length - 1]).toString();
-                parameters = Arrays.copyOfRange(parameters, 0, parameters.length - 1);
+        checkRequiredPageable(returnStgy, values);
 
-                break;
+        if (!qry.isTextQuery()) {
+            if (!qry.isAutogenerated()) {
+                StringQuery squery = new ExpressionBasedStringQuery(queryString, metadata, expressionParser);
+                queryString = squery.getQueryString();
+                parameters = extractBindableValues(parameters, getQueryMethod().getParameters(),
+                    squery.getParameterBindings());
+            }
+            else {
+                // remove dynamic projection from parameters
+                if (hasDynamicProjection)
+                    parameters = ArrayUtils.remove(parameters, dynamicProjectionIndex);
+            }
 
-            case NONE:
-                // No-op.
+            switch (qry.options()) {
+                case SORTING:
+                    queryString = IgniteQueryGenerator
+                        .addSorting(new StringBuilder(queryString), (Sort)values[values.length - 1])
+                        .toString();
+                    if (qry.isAutogenerated())
+                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
+                    break;
+                case PAGINATION:
+                    queryString = IgniteQueryGenerator
+                        .addPaging(new StringBuilder(queryString), (Pageable)values[values.length - 1])
+                        .toString();
+                    if (qry.isAutogenerated())
+                        parameters = Arrays.copyOfRange(parameters, 0, values.length - 1);
+                    break;
+                default:
+            }
+
+            if (qry.isFieldQuery()) {
+                SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(queryString);
+                sqlFieldsQry.setArgs(parameters);
+
+                sqlFieldsQry.setCollocated(config.collocated());
+                sqlFieldsQry.setDistributedJoins(config.distributedJoins());
+                sqlFieldsQry.setEnforceJoinOrder(config.enforceJoinOrder());
+                sqlFieldsQry.setLazy(config.lazy());
+                sqlFieldsQry.setLocal(config.local());
+
+                if (config.parts() != null && config.parts().length > 0)
+                    sqlFieldsQry.setPartitions(config.parts());
+
+                sqlFieldsQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
+
+                query = sqlFieldsQry;
+            }
+            else {
+                SqlQuery sqlQry = new SqlQuery(type, queryString);
+                sqlQry.setArgs(parameters);
+
+                sqlQry.setDistributedJoins(config.distributedJoins());
+                sqlQry.setLocal(config.local());
+
+                if (config.parts() != null && config.parts().length > 0)
+                    sqlQry.setPartitions(config.parts());
+
+                sqlQry.setTimeout(config.timeout(), TimeUnit.MILLISECONDS);
+
+                query = sqlQry;
+            }
+        }
+        else {
+            int pageSize = -1;
+
+            switch (qry.options()) {
+                case PAGINATION:
+                    pageSize = ((Pageable)parameters[parameters.length - 1]).getPageSize();
+                    break;
+            }
+
+            // check if queryString contains SpEL template expressions and evaluate them if any
+            if (queryString.contains("#{")) {
+                EvaluationContext queryEvalContext = queryMethodEvaluationContextProvider
+                    .getEvaluationContext(getQueryMethod().getParameters(),
+                        values);
+
+                Object eval = expressionParser.parseExpression(queryString, ParserContext.TEMPLATE_EXPRESSION)
+                    .getValue(queryEvalContext);
+
+                if (!(eval instanceof String)) {
+                    throw new IllegalStateException(
+                        "TextQuery with SpEL expressions must produce a String response, but found " + eval.getClass()
+                            .getName()
+                            + ". Please, check your expression: " + queryString);
+                }
+                queryString = (String)eval;
+            }
+
+            TextQuery textQuery = new TextQuery(type, queryString, config.limit());
+
+            textQuery.setLocal(config.local());
+
+            if (pageSize > -1)
+                textQuery.setPageSize(pageSize);
+
+            query = textQuery;
+        }
+        return query;
+    }
+
+    /**
+     * @param row SQL result row.
+     * @param cursor SQL query result cursor through which {@param row} was obtained.
+     * @return SQL result row values mapped to corresponding column names.
+     */
+    private static Map<String, Object> rowToMap(final List<?> row, FieldsQueryCursor<?> cursor) {
+        // use treemap with case insensitive property name
+        final TreeMap<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+        for (int i = 0; i < row.size(); i++) {
+            // don't want key or val columns
+            final String fieldName = cursor.getFieldName(i).toLowerCase();
+
+            if (!KEY_FIELD_NAME.equalsIgnoreCase(fieldName) && !VAL_FIELD_NAME.equalsIgnoreCase(fieldName))
+                map.put(fieldName, row.get(i));
         }
 
-        if (qry.isFieldQuery()) {
-            SqlFieldsQuery sqlFieldsQry = new SqlFieldsQuery(sql);
-            sqlFieldsQry.setArgs(parameters);
+        return map;
+    }
 
-            return sqlFieldsQry;
+    /**
+     * convert row ( with list of field values) into domain entity
+     *
+     * @param row SQL query result row.
+     * @param cursor SQL query result cursor through which {@param row} was obtained.
+     * @return Entitiy instance.
+     */
+    private <V> V rowToEntity(List<?> row, FieldsQueryCursor<?> cursor) {
+        Constructor<?> ctor;
+
+        try {
+            ctor = type.getDeclaredConstructor();
+
+            ctor.setAccessible(true);
+        }
+        catch (NoSuchMethodException | SecurityException ignored) {
+            ctor = null;
         }
 
-        SqlQuery sqlQry = new SqlQuery(type, sql);
-        sqlQry.setArgs(parameters);
+        try {
+            Object res = ctor == null ? GridUnsafe.allocateInstance(type) : ctor.newInstance();
 
-        return sqlQry;
+            for (int i = 0; i < row.size(); i++) {
+                Field entityField = domainEntitiyFields.get(cursor.getFieldName(i).toLowerCase());
+
+                if (entityField != null)
+                    FieldUtils.writeField(entityField, res, fixExpectedType(row.get(i), entityField.getType()), true);
+            }
+
+            return (V)res;
+        }
+        catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+            throw new IgniteException("Unable to allocate instance of domain entity class " + type.getName(), e);
+        }
+    }
+
+    /**
+     * Validates operations that requires Pageable parameter
+     *
+     * @param returnStgy Return stgy.
+     * @param prmtrs     Prmtrs.
+     */
+    private void checkRequiredPageable(ReturnStrategy returnStgy, Object[] prmtrs) {
+        try {
+            if (returnStgy == ReturnStrategy.PAGE_OF_VALUES || returnStgy == ReturnStrategy.SLICE_OF_VALUES
+                || returnStgy == ReturnStrategy.SLICE_OF_CACHE_ENTRIES) {
+                Pageable page = (Pageable)prmtrs[prmtrs.length - 1];
+                page.isPaged();
+            }
+        }
+        catch (NullPointerException | IndexOutOfBoundsException | ClassCastException e) {
+            throw new IllegalStateException(
+                "For " + returnStgy.name() + " you must provide on last method parameter a non null Pageable instance");
+        }
+    }
+
+    /**
+     * Ignite QueryCursor wrapper.
+     * <p>
+     * Ensures closing underline cursor when there is no data.
+     *
+     * @param <T> input type
+     * @param <V> transformed output type
+     */
+    public static class QueryCursorWrapper<T, V> extends AbstractCollection<V> implements QueryCursor<V> {
+        /**
+         * Delegate query cursor.
+         */
+        private final QueryCursor<T> delegate;
+
+        /**
+         * Transformer.
+         */
+        private final Function<T, V> transformer;
+
+        /**
+         * Instantiates a new Query cursor wrapper.
+         *
+         * @param delegate    delegate QueryCursor with T input elements
+         * @param transformer Function to transform T to V elements
+         */
+        public QueryCursorWrapper(final QueryCursor<T> delegate, final Function<T, V> transformer) {
+            this.delegate = delegate;
+            this.transformer = transformer;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Iterator<V> iterator() {
+            final Iterator<T> it = delegate.iterator();
+
+            return new Iterator<V>() {
+                /** */
+                @Override public boolean hasNext() {
+                    if (!it.hasNext()) {
+                        U.closeQuiet(delegate);
+                        return false;
+                    }
+                    return true;
+                }
+
+                /** */
+                @Override public V next() {
+                    final V r = transformer.apply(it.next());
+                    if (r != null)
+                        return r;
+                    throw new NoSuchElementException();
+                }
+            };
+        }
+
+        /** {@inheritDoc} */
+        @Override public void close() {
+            U.closeQuiet(delegate);
+        }
+
+        /** {@inheritDoc} */
+        @Override public List<V> getAll() {
+            final List<V> data = new ArrayList<>();
+            delegate.forEach(i -> data.add(transformer.apply(i)));
+            U.closeQuiet(delegate);
+            return data;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int size() {
+            return 0;
+        }
     }
 }
diff --git a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
similarity index 99%
rename from modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
index a44ae6c..ba8c4aa 100644
--- a/modules/spring-data-2.0-ext/src/main/java/org/apache/ignite/springdata20/repository/query/QueryUtils.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/QueryUtils.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata20.repository.query;
+package org.apache.ignite.springdata.repository.query;
 
 import java.util.HashSet;
 import java.util.Set;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
similarity index 99%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
index 01af166..e54552b 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/query/StringQuery.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/StringQuery.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.repository.query;
+package org.apache.ignite.springdata.repository.query;
 
 import java.lang.reflect.Array;
 import java.util.ArrayList;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
index 9b6fdb1..6046af4 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/query/package-info.java
@@ -19,5 +19,4 @@
  * <!-- Package description. -->
  * Package includes classes that integrates with Apache Ignite SQL engine.
  */
-
 package org.apache.ignite.springdata.repository.query;
diff --git a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
similarity index 95%
rename from modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java
rename to modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
index a69dc8e..a407d43 100644
--- a/modules/spring-data-2.2-ext/src/main/java/org/apache/ignite/springdata22/repository/support/ConditionFalse.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/ConditionFalse.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.springdata22.repository.support;
+package org.apache.ignite.springdata.repository.support;
 
 import org.springframework.context.annotation.Condition;
 import org.springframework.context.annotation.ConditionContext;
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
index ba19f93..1f8bf81 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteProxyFactory.java
@@ -17,59 +17,100 @@
 
 package org.apache.ignite.springdata.repository.support;
 
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Stream;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.springdata.proxy.IgniteProxy;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.config.BeanExpressionResolver;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.expression.StandardBeanExpressionResolver;
 
 /**
- * Represents factory for obtaining instance of {@link IgniteProxy} that provide client-independent connection to the
+ * Represents factory for obtaining instances of {@link IgniteProxy} that provide client-independent connection to the
  * Ignite cluster.
  */
-public class IgniteProxyFactory extends AbstractFactoryBean<IgniteProxy> implements ApplicationContextAware {
-    /** Name of the bean that stores Ignite client instance to access the Ignite cluster. */
-    private static final String IGNITE_INSTANCE_BEAN_NAME = "igniteInstance";
+public class IgniteProxyFactory implements ApplicationContextAware, DisposableBean {
+    /** Spring application expression resolver. */
+    private final BeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
 
-    /** Name of the bean that stores the configuration to instantiate the Ignite client. */
-    private static final String IGNITE_CONFIG_BEAN_NAME = "igniteCfg";
-
-    /** Name of the bean that stores the Spring configuration path to instantiate the Ignite client. */
-    private static final String IGNITE_SPRING_CONFIG_PATH_BEAN_NAME= "igniteSpringCfgPath";
+    /** Repositories associated with Ignite proxy. */
+    private final Map<Class<?>, IgniteProxy> igniteProxies = new ConcurrentHashMap<>();
 
     /** Spring application context. */
     private ApplicationContext ctx;
 
+    /** Spring application bean expression context. */
+    private BeanExpressionContext beanExpressionCtx;
+
+    /**
+     * @param repoInterface The repository interface class for which {@link IgniteProxy} will be created.
+     * @return {@link IgniteProxy} instance.
+     */
+    public IgniteProxy igniteProxy(Class<?> repoInterface) {
+        return igniteProxies.computeIfAbsent(repoInterface, k -> createIgniteProxy(repoInterface));
+    }
+
     /** {@inheritDoc} */
     @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
         this.ctx = ctx;
+
+        beanExpressionCtx = new BeanExpressionContext(
+            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
+            null);
     }
 
     /** {@inheritDoc} */
     @Override public void destroy() throws Exception {
-        Object igniteProxy = getObject();
+        Set<IgniteProxy> proxies = new HashSet<>(igniteProxies.values());
 
-        if (igniteProxy instanceof AutoCloseable)
-            ((AutoCloseable)igniteProxy).close();
+        Exception destroyE = null;
+
+        for (IgniteProxy proxy : proxies) {
+            if (proxy instanceof AutoCloseable) {
+                try {
+                    ((AutoCloseable)proxy).close();
+                }
+                catch (Exception e) {
+                    if (destroyE == null)
+                        destroyE = e;
+                    else
+                        destroyE.addSuppressed(e);
+                }
+            }
+        }
+
+        if (destroyE != null)
+            throw destroyE;
     }
 
-    /** {@inheritDoc} */
-    @Override public Class<?> getObjectType() {
-        return IgniteProxy.class;
-    }
+    /**
+     * Creates {@link IgniteProxy} to be used for providing access to the Ignite cluster for specified repository.
+     *
+     * @param repoInterface {@link Class} instance of the repository interface.
+     * @return Instance of {@link IgniteProxy} associated with specified repository.
+     *
+     * @see RepositoryConfig
+     */
+    private IgniteProxy createIgniteProxy(Class<?> repoInterface) {
+        RepositoryConfig repoCfg = IgniteRepositoryFactory.getRepositoryConfiguration(repoInterface);
 
-    /** {@inheritDoc} */
-    @Override protected IgniteProxy createInstance() {
         return Stream.<BeanFinder>of(
-            () -> ctx.getBean(IGNITE_INSTANCE_BEAN_NAME),
-            () -> ctx.getBean(IGNITE_CONFIG_BEAN_NAME),
-            () -> ctx.getBean(IGNITE_SPRING_CONFIG_PATH_BEAN_NAME, String.class),
+            () -> ctx.getBean(evaluateExpression(repoCfg.igniteInstance())),
+            () -> ctx.getBean(evaluateExpression(repoCfg.igniteCfg())),
+            () -> ctx.getBean(evaluateExpression(repoCfg.igniteSpringCfgPath()), String.class),
             () -> ctx.getBean(Ignite.class),
             () -> ctx.getBean(IgniteClient.class),
             () -> ctx.getBean(IgniteConfiguration.class),
@@ -79,15 +120,25 @@
             .findFirst()
             .map(IgniteProxy::of)
             .orElseThrow(() -> {
-                return new IllegalArgumentException("No beans were found that provide connection configuration to" +
-                    " the Ignite cluster. One of the beans with the following names is required : \"" +
-                    IGNITE_INSTANCE_BEAN_NAME + "\", \"" + IGNITE_CONFIG_BEAN_NAME + "\" or \"" +
-                    IGNITE_SPRING_CONFIG_PATH_BEAN_NAME + "\". You can also provide Ignite, IgniteClient," +
-                    " IgniteConfiguration or ClientConfiguration bean to application context.");
+                return new IllegalArgumentException("Invalid configuration for repository " +
+                    repoInterface.getName() + ". No beans were found that provide connection configuration to the" +
+                    " Ignite cluster. Check \"igniteInstance\", \"igniteCfg\", \"igniteSpringCfgPath\" parameters" +
+                    " of " + RepositoryConfig.class.getName() + " repository annotation or provide Ignite, IgniteClient, " +
+                    " ClientConfiguration or IgniteConfiguration bean to application context.");
             });
     }
 
     /**
+     * Evaluates the SpEL expression.
+     *
+     * @param spelExpression SpEL expression
+     * @return The result of evaluation of the SpEL expression.
+     */
+    private String evaluateExpression(String spelExpression) {
+        return (String)expressionResolver.evaluate(spelExpression, beanExpressionCtx);
+    }
+
+    /**
      * Helper interface that wraps getBean method.
      */
     @FunctionalInterface
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
index 8649733..56e3e21 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactory.java
@@ -16,63 +16,90 @@
  */
 package org.apache.ignite.springdata.repository.support;
 
-import java.io.Serializable;
-import java.lang.reflect.Method;
+import java.util.Optional;
 import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
 import org.apache.ignite.springdata.proxy.IgniteProxy;
-import org.apache.ignite.springdata.repository.config.Query;
-import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.apache.ignite.springdata.repository.query.IgniteQuery;
 import org.apache.ignite.springdata.repository.query.IgniteQueryGenerator;
 import org.apache.ignite.springdata.repository.query.IgniteRepositoryQuery;
-import org.springframework.data.projection.ProjectionFactory;
+import org.apache.ignite.springdata.repository.config.DynamicQueryConfig;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.beans.factory.config.BeanExpressionContext;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.expression.StandardBeanExpressionResolver;
 import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.data.repository.core.NamedQueries;
 import org.springframework.data.repository.core.RepositoryInformation;
 import org.springframework.data.repository.core.RepositoryMetadata;
 import org.springframework.data.repository.core.support.AbstractEntityInformation;
 import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.data.repository.query.EvaluationContextProvider;
 import org.springframework.data.repository.query.QueryLookupStrategy;
-import org.springframework.data.repository.query.RepositoryQuery;
+import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 
 /**
  * Crucial for spring-data functionality class. Create proxies for repositories.
+ * <p>
+ * Supports multiple Ignite Instances on same JVM.
+ * <p>
+ * This is pretty useful working with Spring repositories bound to different Ignite intances within same application.
+ *
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
 public class IgniteRepositoryFactory extends RepositoryFactorySupport {
+    /** Spring application expression resolver */
+    private final StandardBeanExpressionResolver resolver = new StandardBeanExpressionResolver();
+
+    /** Spring application bean expression context */
+    private final BeanExpressionContext beanExpressionContext;
+
     /** Ignite cache proxy instance associated with the current repository. */
     private final IgniteCacheProxy<?, ?> cache;
 
+    /** Ignite proxy instance associated with the current repository. */
+    private final IgniteProxy ignite;
+
     /**
-     * Creates the factory with initialized {@link IgniteProxy} instance.
-     *
-     * @param ignite Ignite proxy instance.
+     * @param ctx Spring Application context.
      * @param repoInterface Repository interface.
      */
-    public IgniteRepositoryFactory(IgniteProxy ignite, Class<?> repoInterface) {
-        RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
+    public IgniteRepositoryFactory(ApplicationContext ctx, Class<?> repoInterface) {
+        ignite = ctx.getBean(IgniteProxy.class, repoInterface);
 
-        Assert.notNull(cfg, "Invalid repository configuration [name=" + repoInterface.getName() + "]. " +
-            RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
+        beanExpressionContext = new BeanExpressionContext(
+            new DefaultListableBeanFactory(ctx.getAutowireCapableBeanFactory()),
+            null);
 
-        String cacheName = cfg.cacheName();
+        RepositoryConfig cfg = getRepositoryConfiguration(repoInterface);
 
-        Assert.hasText(cacheName, "Invalid repository configuration [name=" + repoInterface.getName() + "]." +
-            " Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
+        String cacheName = evaluateExpression(cfg.cacheName());
+
+        Assert.hasText(cacheName, "Invalid configuration for repository " + repoInterface.getName() +
+            ". Set a name of an Apache Ignite cache using " + RepositoryConfig.class.getName() +
             " annotation to map this repository to the underlying cache.");
 
-        cache = ignite.getOrCreateCache(cacheName);
+       cache = cfg.autoCreateCache() ? ignite.getOrCreateCache(cacheName) : ignite.cache(cacheName);
+
+        if (cache == null) {
+            throw new IllegalArgumentException(
+                "Cache '" + cacheName + "' not found for repository interface " + repoInterface.getName()
+                    + ". Please, add a cache configuration to ignite configuration"
+                    + " or pass autoCreateCache=true to " + RepositoryConfig.class.getName() + " annotation.");
+        }
     }
 
     /** {@inheritDoc} */
-    @Override public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
+    @Override public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
         return new AbstractEntityInformation<T, ID>(domainClass) {
+            /** {@inheritDoc} */
             @Override public ID getId(T entity) {
                 return null;
             }
 
+            /** {@inheritDoc} */
             @Override public Class<ID> getIdType() {
                 return null;
             }
@@ -84,51 +111,96 @@
         return IgniteRepositoryImpl.class;
     }
 
-    /** {@inheritDoc} */
-    @Override protected Object getTargetRepository(RepositoryInformation metadata) {
-        return getTargetRepositoryViaReflection(metadata, cache);
+    /**
+     * Evaluate the SpEL expression
+     *
+     * @param spelExpression SpEL expression
+     * @return the result of execution of the SpEL expression
+     */
+    private String evaluateExpression(String spelExpression) {
+        return (String)resolver.evaluate(spelExpression, beanExpressionContext);
     }
 
     /** {@inheritDoc} */
-    @Override protected QueryLookupStrategy getQueryLookupStrategy(final QueryLookupStrategy.Key key,
-        EvaluationContextProvider evaluationCtxProvider) {
+    @Override protected Object getTargetRepository(RepositoryInformation metadata) {
+        return getTargetRepositoryViaReflection(metadata, ignite, cache);
+    }
 
-        return new QueryLookupStrategy() {
-            @Override public RepositoryQuery resolveQuery(final Method mtd, final RepositoryMetadata metadata,
-                final ProjectionFactory factory, NamedQueries namedQueries) {
+    /** {@inheritDoc} */
+    @Override protected Optional<QueryLookupStrategy> getQueryLookupStrategy(final QueryLookupStrategy.Key key,
+        QueryMethodEvaluationContextProvider evaluationContextProvider) {
+        return Optional.of((mtd, metadata, factory, namedQueries) -> {
+            final Query annotation = mtd.getAnnotation(Query.class);
+            if (annotation != null && (StringUtils.hasText(annotation.value()) || annotation.textQuery() || annotation
+                .dynamicQuery())) {
 
-                final Query annotation = mtd.getAnnotation(Query.class);
+                String qryStr = annotation.value();
 
-                if (annotation != null) {
-                    String qryStr = annotation.value();
+                boolean annotatedIgniteQuery = !annotation.dynamicQuery() && (StringUtils.hasText(qryStr) || annotation
+                    .textQuery());
 
-                    if (key != Key.CREATE && StringUtils.hasText(qryStr))
-                        return new IgniteRepositoryQuery(metadata,
-                            new IgniteQuery(qryStr, isFieldQuery(qryStr), IgniteQueryGenerator.getOptions(mtd)),
-                            mtd, factory, cache);
+                IgniteQuery query = annotatedIgniteQuery ? new IgniteQuery(qryStr,
+                    !annotation.textQuery() && (isFieldQuery(qryStr) || annotation.forceFieldsQuery()),
+                    annotation.textQuery(), false, IgniteQueryGenerator.getOptions(mtd)) : null;
+
+                if (key != QueryLookupStrategy.Key.CREATE) {
+                    return new IgniteRepositoryQuery(metadata, query, mtd, factory, cache,
+                        annotatedIgniteQuery ? DynamicQueryConfig.fromQueryAnnotation(annotation) : null,
+                        evaluationContextProvider);
                 }
-
-                if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY)
-                    throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass " +
-                        "a query string via org.apache.ignite.springdata.repository.config.Query annotation.");
-
-                return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd,
-                    factory, cache);
             }
-        };
+
+            if (key == QueryLookupStrategy.Key.USE_DECLARED_QUERY) {
+                throw new IllegalStateException("To use QueryLookupStrategy.Key.USE_DECLARED_QUERY, pass "
+                    + "a query string via org.apache.ignite.springdata.repository"
+                    + ".config.Query annotation.");
+            }
+
+            return new IgniteRepositoryQuery(metadata, IgniteQueryGenerator.generateSql(mtd, metadata), mtd, factory,
+                cache, DynamicQueryConfig.fromQueryAnnotation(annotation), evaluationContextProvider);
+        });
     }
 
     /**
      * @param qry Query string.
-     * @return {@code true} if query is SQLFieldsQuery.
+     * @return {@code true} if query is SqlFieldsQuery.
      */
-    private boolean isFieldQuery(String qry) {
-        return qry.matches("^SELECT.*") && !qry.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+    public static boolean isFieldQuery(String qry) {
+        String qryUpperCase = qry.toUpperCase();
+
+        return isStatement(qryUpperCase) && !qryUpperCase.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+    }
+
+    /**
+     * Evaluates if the query starts with a clause.<br>
+     * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
+     *
+     * @param qryUpperCase Query string in upper case.
+     * @return {@code true} if query is full SQL statement.
+     */
+    private static boolean isStatement(String qryUpperCase) {
+        return qryUpperCase.matches("^\\s*SELECT\\b.*") ||
+            // update
+            qryUpperCase.matches("^\\s*UPDATE\\b.*") ||
+            // delete
+            qryUpperCase.matches("^\\s*DELETE\\b.*") ||
+            // merge
+            qryUpperCase.matches("^\\s*MERGE\\b.*") ||
+            // insert
+            qryUpperCase.matches("^\\s*INSERT\\b.*");
+    }
+
+    /**
+     * @return Configuration of the specified repository.
+     * @throws IllegalArgumentException If no configuration is specified.
+     * @see RepositoryConfig
+     */
+    static RepositoryConfig getRepositoryConfiguration(Class<?> repoInterface) {
+        RepositoryConfig cfg = repoInterface.getAnnotation(RepositoryConfig.class);
+
+        Assert.notNull(cfg, "Invalid configuration for repository " + repoInterface.getName() + ". " +
+            RepositoryConfig.class.getName() + " annotation must be specified for each repository interface.");
+
+        return cfg;
     }
 }
-
-
-
-
-
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
index 3028cea..5b15ba5 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryFactoryBean.java
@@ -19,47 +19,50 @@
 
 import java.io.Serializable;
 import org.apache.ignite.Ignite;
-import org.apache.ignite.client.IgniteClient;
-import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.springdata.proxy.IgniteProxy;
 import org.apache.ignite.springdata.repository.IgniteRepository;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
 import org.springframework.data.repository.Repository;
 import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
 import org.springframework.data.repository.core.support.RepositoryFactorySupport;
 
 /**
  * Apache Ignite repository factory bean.
- *
- * The repository requires to define one of the parameters below in your Spring application configuration in order
- * to get an access to Apache Ignite cluster:
+ * <p>
+ * The {@link RepositoryConfig} requires to define one of the
+ * parameters below in your Spring application configuration in order to get an access to Apache Ignite cluster:
  * <ul>
- * <li>{@link Ignite} or {@link IgniteClient} instance bean named "igniteInstance"</li>
- * <li>{@link IgniteConfiguration} or {@link ClientConfiguration} bean named "igniteCfg"</li>
- * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath"</li>
+ * <li>{@link Ignite} instance bean</li>
+ * <li>{@link IgniteConfiguration} bean</li>
+ * <li>A path to Ignite's Spring XML configuration named "igniteSpringCfgPath" by default</li>
  * <ul/>
  *
  * @param <T> Repository type, {@link IgniteRepository}
- * @param <S> Domain object class.
- * @param <ID> Domain object key, super expects {@link Serializable}.
+ * @param <V> Domain object class.
+ * @param <K> Domain object key, super expects {@link Serializable}.
  */
-public class IgniteRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
-    extends RepositoryFactoryBeanSupport<T, S, ID> {
-    /** Ignite proxy. */
-    @Autowired
-    private IgniteProxy ignite;
+public class IgniteRepositoryFactoryBean<T extends Repository<V, K>, V, K extends Serializable>
+    extends RepositoryFactoryBeanSupport<T, V, K> implements ApplicationContextAware {
+    /** */
+    private ApplicationContext ctx;
 
     /**
-     * @param repositoryInterface Repository interface.
+     * @param repoInterface Repository interface.
      */
-    protected IgniteRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
-        super(repositoryInterface);
+    protected IgniteRepositoryFactoryBean(Class<? extends T> repoInterface) {
+        super(repoInterface);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+        this.ctx = ctx;
     }
 
     /** {@inheritDoc} */
     @Override protected RepositoryFactorySupport createRepositoryFactory() {
-        return new IgniteRepositoryFactory(ignite, getObjectType());
+        return new IgniteRepositoryFactory(ctx, getObjectType());
     }
 }
-
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
index e8b8824..291877f 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/IgniteRepositoryImpl.java
@@ -17,83 +17,154 @@
 package org.apache.ignite.springdata.repository.support;
 
 import java.io.Serializable;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TreeSet;
 import javax.cache.Cache;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CachePeekMode;
 import org.apache.ignite.springdata.proxy.IgniteCacheProxy;
+import org.apache.ignite.springdata.proxy.IgniteNodeCacheProxy;
+import org.apache.ignite.springdata.proxy.IgniteProxy;
+import org.apache.ignite.springdata.proxy.IgniteNodeProxy;
 import org.apache.ignite.springdata.repository.IgniteRepository;
-
-import static java.util.Collections.emptySet;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.context.annotation.Conditional;
 
 /**
- * General Apache Ignite repository implementation.
+ * General Apache Ignite repository implementation. This bean should've never been loaded by context directly, only via
+ * {@link IgniteRepositoryFactory}
+ *
+ * @param <V> the cache value type
+ * @param <K> the cache key type
+ * @author Apache Ignite Team
+ * @author Manuel Núñez (manuel.nunez@hawkore.com)
  */
-public class IgniteRepositoryImpl<T, ID extends Serializable> implements IgniteRepository<T, ID> {
-    /** Ignite Cache bound to the repository */
-    private final IgniteCacheProxy<ID, T> cache;
+@Conditional(ConditionFalse.class)
+public class IgniteRepositoryImpl<V, K extends Serializable> implements IgniteRepository<V, K> {
+    /** Error message indicating that operation is supported only if {@link Ignite} instance is used to access the cluster. */
+    private static final String UNSUPPORTED_ERR_MSG = "Current operation is supported only if Ignite node instance is" +
+        " used to access the Ignite cluster. See " + RepositoryConfig.class.getName() + "#igniteInstance.";
+
+    /**
+     * Ignite Cache bound to the repository
+     */
+    private final IgniteCacheProxy<K, V> cache;
+
+    /**
+     * Ignite instance bound to the repository
+     */
+    private final IgniteProxy ignite;
 
     /**
      * Repository constructor.
      *
-     * @param cache Initialized cache instance.
+     * @param ignite the ignite
+     * @param cache  Initialized cache instance.
      */
-    public IgniteRepositoryImpl(IgniteCacheProxy<ID, T> cache) {
+    public IgniteRepositoryImpl(IgniteProxy ignite, IgniteCacheProxy<K, V> cache) {
         this.cache = cache;
+        this.ignite = ignite;
     }
 
     /** {@inheritDoc} */
-    @Override public <S extends T> S save(ID key, S entity) {
+    @Override public IgniteCache<K, V> cache() {
+        if (cache instanceof IgniteNodeCacheProxy)
+            return ((IgniteNodeCacheProxy<K, V>)cache).delegate();
+
+        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Ignite ignite() {
+        if (ignite instanceof IgniteNodeProxy)
+            return ((IgniteNodeProxy)ignite).delegate();
+
+        throw new UnsupportedOperationException(UNSUPPORTED_ERR_MSG);
+    }
+
+    /** {@inheritDoc} */
+    @Override public <S extends V> S save(K key, S entity) {
         cache.put(key, entity);
 
         return entity;
     }
 
     /** {@inheritDoc} */
-    @Override public <S extends T> Iterable<S> save(Map<ID, S> entities) {
+    @Override public <S extends V> Iterable<S> save(Map<K, S> entities) {
         cache.putAll(entities);
 
         return entities.values();
     }
 
     /** {@inheritDoc} */
-    @Override public <S extends T> S save(S entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
+    @Override public <S extends V> S save(K key, S entity, @Nullable ExpiryPolicy expiryPlc) {
+        if (expiryPlc != null)
+            cache.withExpiryPolicy(expiryPlc).put(key, entity);
+        else
+            cache.put(key, entity);
+        return entity;
     }
 
     /** {@inheritDoc} */
-    @Override public <S extends T> Iterable<S> save(Iterable<S> entities) {
+    @Override public <S extends V> Iterable<S> save(Map<K, S> entities, @Nullable ExpiryPolicy expiryPlc) {
+        if (expiryPlc != null)
+            cache.withExpiryPolicy(expiryPlc).putAll(entities);
+        else
+            cache.putAll(entities);
+        return entities.values();
+    }
+
+    /**
+     * Not implemented.
+     */
+    @Override public <S extends V> S save(S entity) {
+        throw new UnsupportedOperationException("Use IgniteRepository.save(key,value) method instead.");
+    }
+
+    /**
+     * Not implemented.
+     */
+    @Override public <S extends V> Iterable<S> saveAll(Iterable<S> entities) {
         throw new UnsupportedOperationException("Use IgniteRepository.save(Map<keys,value>) method instead.");
     }
 
     /** {@inheritDoc} */
-    @Override public T findOne(ID id) {
-        return cache.get(id);
+    @Override public Optional<V> findById(K id) {
+        return Optional.ofNullable(cache.get(id));
     }
 
     /** {@inheritDoc} */
-    @Override public boolean exists(ID id) {
+    @Override public boolean existsById(K id) {
         return cache.containsKey(id);
     }
 
     /** {@inheritDoc} */
-    @Override public Iterable<T> findAll() {
-        final Iterator<Cache.Entry<ID, T>> iter = cache.iterator();
+    @Override public Iterable<V> findAll() {
+        final Iterator<Cache.Entry<K, V>> iter = cache.iterator();
 
-        return new Iterable<T>() {
-            @Override public Iterator<T> iterator() {
-                return new Iterator<T>() {
+        return new Iterable<V>() {
+            /** */
+            @Override public Iterator<V> iterator() {
+                return new Iterator<V>() {
+                    /** {@inheritDoc} */
                     @Override public boolean hasNext() {
                         return iter.hasNext();
                     }
 
-                    @Override public T next() {
+                    /** {@inheritDoc} */
+                    @Override public V next() {
                         return iter.next().getValue();
                     }
 
+                    /** {@inheritDoc} */
                     @Override public void remove() {
                         iter.remove();
                     }
@@ -102,37 +173,20 @@
         };
     }
 
-    /**
-     * @param ids Collection of IDs.
-     * @return Collection transformed to set.
-     */
-    private Set<ID> toSet(Iterable<ID> ids) {
-        if (ids instanceof Set)
-            return (Set<ID>)ids;
-
-        Iterator<ID> itr = ids.iterator();
-
-        if (!itr.hasNext())
-            return emptySet();
-
-        ID key = itr.next();
-
-        Set<ID> keys = key instanceof Comparable ? new TreeSet<>() : new HashSet<>();
-
-        keys.add(key);
-
-        while (itr.hasNext()) {
-            key = itr.next();
-
-            keys.add(key);
-        }
-
-        return keys;
-    }
-
     /** {@inheritDoc} */
-    @Override public Iterable<T> findAll(Iterable<ID> ids) {
-        return cache.getAll(toSet(ids)).values();
+    @Override public Iterable<V> findAllById(Iterable<K> ids) {
+        if (ids instanceof Set)
+            return cache.getAll((Set<K>)ids).values();
+
+        if (ids instanceof Collection)
+            return cache.getAll(new HashSet<>((Collection<K>)ids)).values();
+
+        TreeSet<K> keys = new TreeSet<>();
+
+        for (K id : ids)
+            keys.add(id);
+
+        return cache.getAll(keys).values();
     }
 
     /** {@inheritDoc} */
@@ -141,23 +195,38 @@
     }
 
     /** {@inheritDoc} */
-    @Override public void delete(ID id) {
+    @Override public void deleteById(K id) {
         cache.remove(id);
     }
 
     /** {@inheritDoc} */
-    @Override public void delete(T entity) {
-        throw new UnsupportedOperationException("Use IgniteRepository.delete(key) method instead.");
+    @Override public void delete(V entity) {
+        throw new UnsupportedOperationException("Use IgniteRepository.deleteById(key) method instead.");
     }
 
     /** {@inheritDoc} */
-    @Override public void delete(Iterable<? extends T> entities) {
-        throw new UnsupportedOperationException("Use IgniteRepository.deleteAll(keys) method instead.");
+    @Override public void deleteAll(Iterable<? extends V> entities) {
+        throw new UnsupportedOperationException("Use IgniteRepository.deleteAllById(keys) method instead.");
     }
 
     /** {@inheritDoc} */
-    @Override public void deleteAll(Iterable<ID> ids) {
-        cache.removeAll(toSet(ids));
+    @Override public void deleteAllById(Iterable<? extends K> ids) {
+        if (ids instanceof Set) {
+            cache.removeAll((Set<K>)ids);
+            return;
+        }
+
+        if (ids instanceof Collection) {
+            cache.removeAll(new HashSet<>((Collection<K>)ids));
+            return;
+        }
+
+        TreeSet<K> keys = new TreeSet<>();
+
+        for (K id : ids)
+            keys.add(id);
+
+        cache.removeAll(keys);
     }
 
     /** {@inheritDoc} */
diff --git a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
index 749c9e7..58c5bb8 100644
--- a/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
+++ b/modules/spring-data-ext/src/main/java/org/apache/ignite/springdata/repository/support/package-info.java
@@ -19,5 +19,4 @@
  * <!-- Package description. -->
  * Package contains supporting files required by Spring Data framework.
  */
-
 package org.apache.ignite.springdata.repository.support;
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
index 6dcadb8..ec2e7ca 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCompoundKeyTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.springdata;
 
+import org.apache.ignite.Ignite;
 import org.apache.ignite.springdata.compoundkey.CityRepository;
 import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -32,4 +33,9 @@
 
         repo = ctx.getBean(CityRepository.class);
     }
+
+    /** {@inheritDoc} */
+    @Override protected Ignite ignite() {
+        return ctx.getBean("igniteServerNode", Ignite.class);
+    }
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
index 751eb09..226ee9b 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataCrudSelfTest.java
@@ -17,23 +17,30 @@
 
 package org.apache.ignite.springdata;
 
-import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
 import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryWithCompoundKey;
+import org.apache.ignite.testframework.GridTestUtils;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
 /** Tests Spring Data CRUD operation when thin client is used for accessing the Ignite cluster. */
 public class IgniteClientSpringDataCrudSelfTest extends IgniteSpringDataCrudSelfTest {
     /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() {
+    @Override protected void beforeTestsStarted() throws Exception {
         ctx = new AnnotationConfigApplicationContext();
 
         ctx.register(IgniteClientApplicationConfiguration.class);
         ctx.refresh();
 
         repo = ctx.getBean(PersonRepository.class);
-        repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
-        ignite = ctx.getBean(IgniteEx.class);
+    }
+
+    /** Text queries are not supported when {@link IgniteClient} is used for acessing the Ignite cluster. */
+    @Override public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
+        GridTestUtils.assertThrows(log,
+            () -> repo.textQueryByFirstNameWithProjectionNamedParameter("person"), IllegalStateException.class,
+            "Query of type TextQuery is not supported by thin client. Check" +
+                " org.apache.ignite.springdata.misc.PersonRepository#textQueryByFirstNameWithProjectionNamedParameter" +
+                " method configuration or use Ignite node instance to connect to the Ignite cluster.");
     }
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
index 0410e20..27d3645 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteClientSpringDataQueriesSelfTest.java
@@ -20,6 +20,7 @@
 import org.apache.ignite.springdata.misc.IgniteClientApplicationConfiguration;
 import org.apache.ignite.springdata.misc.Person;
 import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
 import org.apache.ignite.springdata.misc.PersonSecondRepository;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
@@ -34,10 +35,13 @@
 
         repo = ctx.getBean(PersonRepository.class);
         repo2 = ctx.getBean(PersonSecondRepository.class);
+        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
 
         for (int i = 0; i < CACHE_SIZE; i++) {
             repo.save(i, new Person("person" + Integer.toHexString(i),
                 "lastName" + Integer.toHexString((i + 16) % 256)));
+            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
         }
     }
 }
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundExtendedKeyTest.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
index 655ef40..d3ccf5e 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCompoundKeyTest.java
@@ -19,8 +19,12 @@
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.springdata.compoundkey.City;
+import org.apache.ignite.springdata.compoundkey.CityKey;
 import org.apache.ignite.springdata.compoundkey.CityRepository;
 import org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -48,12 +52,18 @@
     /** Count Afganistan cities */
     private static final int AFG_COUNT = 4;
 
+    /** Kabul identifier */
+    private static final int KABUL_ID = 1;
+
     /** Quandahar identifier */
     private static final int QUANDAHAR_ID = 2;
 
     /** Afganistan county code */
     private static final String AFG = "AFG";
 
+    /** test city Kabul */
+    protected static final City KABUL = new City("Kabul", "Kabol", 1780000);
+
     /** test city Quandahar */
     private static final City QUANDAHAR = new City("Qandahar","Qandahar", 237500);
 
@@ -78,7 +88,18 @@
 
         loadData();
 
-        assertEquals(TOTAL_COUNT, repo.count());
+        assertEquals(getTotalCount(), repo.count());
+    }
+
+    /**
+     * Clear data
+     * */
+    @Override protected void afterTest() throws Exception {
+        repo.deleteAll();
+
+        assertEquals(0, repo.count());
+
+        super.afterTest();
     }
 
     /**
@@ -88,9 +109,9 @@
         ctx.close();
     }
 
-    /** load data*/
+    /** Load data. */
     public void loadData() throws Exception {
-        Ignite ignite = ctx.getBean(Ignite.class);
+        Ignite ignite = ignite();
 
         if (ignite.cacheNames().contains(CACHE_NAME))
             ignite.destroyCache(CACHE_NAME);
@@ -112,7 +133,32 @@
     /** Test */
     @Test
     public void test() {
+        assertEquals(Optional.of(KABUL), repo.findById(new CityKey(KABUL_ID, AFG)));
         assertEquals(AFG_COUNT, repo.findByCountryCode(AFG).size());
         assertEquals(QUANDAHAR, repo.findById(QUANDAHAR_ID));
     }
+
+    /** Test. */
+    @Test
+    public void deleteAllById() {
+        Set<CityKey> keys = new HashSet<>();
+        keys.add(new CityKey(1, "AFG"));
+        keys.add(new CityKey(2, "AFG"));
+        keys.add(new CityKey(3, "AFG"));
+        keys.add(new CityKey(4, "AFG"));
+        keys.add(new CityKey(5, "NLD"));
+
+        repo.deleteAllById(keys);
+        assertEquals(0, repo.count());
+    }
+
+    /** */
+    protected Ignite ignite() {
+        return ctx.getBean(Ignite.class);
+    }
+
+    /** Total count of entries after load data. */
+    protected int getTotalCount() {
+        return TOTAL_COUNT;
+    }
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
index 5d5fbae..55d3fe6 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataConnectionConfigurationTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.springdata;
 
+import java.io.Serializable;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
@@ -28,12 +29,9 @@
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonRepository;
 import org.apache.ignite.springdata.repository.IgniteRepository;
 import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
 import org.apache.ignite.springdata.repository.config.RepositoryConfig;
-import org.apache.ignite.springdata.repository.support.IgniteProxyFactory;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -67,7 +65,7 @@
     /** Tests repository configuration in case {@link IgniteConfiguration} is used to access the Ignite cluster. */
     @Test
     public void testRepositoryWithIgniteConfiguration() {
-        checkRepositoryConfiguration(IgniteConfigurationApplication.class);
+        checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
 
         assertClientNodeIsStopped();
     }
@@ -75,41 +73,41 @@
     /** Tests repository configuration in case {@link ClientConfiguration} is used to access the Ignite cluster. */
     @Test
     public void testRepositoryWithClientConfiguration() {
-        checkRepositoryConfiguration(ClientConfigurationApplication.class);
+        checkRepositoryConfiguration(ClientConfigurationApplication.class, IgniteClientConfigRepository.class);
     }
 
     /** Tests repository configuration in case {@link Ignite} with non default is used to access the Ignite cluster. */
     @Test
-    public void testRepositoryWithNonDefaultIgniteBean() {
-        checkRepositoryConfiguration(NonDefaultIgniteBeanApplication.class);
+    public void testRepositoryWithoutIgniteInstanceParameter() {
+        checkRepositoryConfiguration(DefaultIgniteBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
     }
 
     /** Tests repository configuration in case {@link IgniteClient} with non default name is used to access the Ignite cluster. */
     @Test
-    public void testRepositoryWithNonDefaultIgniteClientBean() {
-        checkRepositoryConfiguration(NonDefaultIgniteClientBeanApplication.class);
+    public void testRepositoryWithoutIgniteClientInstanceParameter() {
+        checkRepositoryConfiguration(DefaultIgniteClientBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
     }
 
     /** Tests repository configuration in case {@link ClientConfiguration} with non default name is used to access the Ignite cluster. */
     @Test
-    public void testRepositoryWithNonDefaultIgniteClientConfigurationBean() {
-        checkRepositoryConfiguration(NonDefaultIgniteClientConfigurationBeanApplication.class);
+    public void testRepositoryWithoutIgnitClientConfigurationParameter() {
+        checkRepositoryConfiguration(DefaultIgniteClientConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
     }
 
     /** Tests repository configuration in case {@link IgniteConfiguration} with non default name is used to access the Ignite cluster. */
     @Test
-    public void testRepositoryWithNonDefaultIgniteConfigurationBean() {
-        checkRepositoryConfiguration(NonDefaultIgniteConfigurationBeanApplication.class);
+    public void testRepositoryWithoutIgniteConfigurationParameter() {
+        checkRepositoryConfiguration(DefaultIgniteConfigurationBeanApplication.class, IgniteRepositoryWithoutExplicitIgnite.class);
     }
 
     /**
      * Tests repository configuration in case {@link IgniteConfiguration} that refers to existing Ignite node instance
-     * is used to access the Ignite cluster.
+     * used to access the Ignite cluster.
      */
     @Test
     public void testRepositoryWithExistingIgniteInstance() throws Exception {
         try (Ignite ignored = startGrid(getIgniteConfiguration(CLI_NAME, true))) {
-            checkRepositoryConfiguration(IgniteConfigurationApplication.class);
+            checkRepositoryConfiguration(IgniteConfigurationApplication.class, IgniteConfigRepository.class);
 
             assertNotNull(Ignition.ignite(CLI_NAME));
         }
@@ -128,9 +126,10 @@
                     return null;
                 },
                 IllegalArgumentException.class,
-                "Invalid repository configuration [name=" + InvalidCacheRepository.class.getName() + "]. Set a" +
-                    " name of an Apache Ignite cache using org.apache.ignite.springdata.repository.config.RepositoryConfig" +
-                    " annotation to map this repository to the underlying cache.");
+                "Cache 'invalidCache' not found for repository interface" +
+                    " org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest$InvalidCacheNameRepository." +
+                    " Please, add a cache configuration to ignite configuration or pass autoCreateCache=true to" +
+                    " org.apache.ignite.springdata.repository.config.RepositoryConfig annotation.");
         }
 
         assertClientNodeIsStopped();
@@ -159,21 +158,24 @@
      * Checks that repository created based on specified Spring application configuration is properly initialized and
      * got access to the Ignite cluster.
      */
-    private void checkRepositoryConfiguration(Class<?> cfgCls) {
+    private void checkRepositoryConfiguration(
+        Class<?> cfgCls,
+        Class<? extends IgniteRepository<Object, Serializable>> repoCls
+    ) {
         try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
             ctx.register(cfgCls);
             ctx.refresh();
 
-            PersonRepository repo = ctx.getBean(PersonRepository.class);
+            IgniteRepository<Object, Serializable> repo = ctx.getBean(repoCls);
 
-            IgniteCache<Integer, Person> cache = grid(SRV_NAME).cache(CACHE_NAME);
+            IgniteCache<Object, Serializable> cache = grid(SRV_NAME).cache(CACHE_NAME);
 
             assertEquals(0, repo.count());
             assertEquals(0, cache.size());
 
             int key = 0;
 
-            repo.save(key, new Person("Domenico", "Scarlatti"));
+            repo.save(key, "1");
 
             assertEquals(1, repo.count());
             assertNotNull(cache.get(key));
@@ -185,11 +187,13 @@
      * for accessing the cluster.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
-    public static class IgniteConfigurationApplication {
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheNameRepository.class))
+    public static class InvalidCacheNameApplication {
         /** Ignite configuration bean. */
         @Bean
-        public IgniteConfiguration igniteCfg() {
+        public IgniteConfiguration igniteConfiguration() {
             return getIgniteConfiguration(CLI_NAME, true);
         }
     }
@@ -201,11 +205,11 @@
     @Configuration
     @EnableIgniteRepositories(
         considerNestedRepositories = true,
-        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = InvalidCacheRepository.class))
-    public static class InvalidCacheNameApplication {
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteConfigRepository.class))
+    public static class IgniteConfigurationApplication {
         /** Ignite configuration bean. */
         @Bean
-        public IgniteConfiguration igniteCfg() {
+        public IgniteConfiguration igniteConfiguration() {
             return getIgniteConfiguration(CLI_NAME, true);
         }
     }
@@ -215,22 +219,27 @@
      * for accessing the cluster.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteClientConfigRepository.class))
     public static class ClientConfigurationApplication {
         /** Ignite client configuration bean. */
         @Bean
-        public ClientConfiguration igniteCfg() {
+        public ClientConfiguration clientConfiguration() {
             return new ClientConfiguration().setAddresses(LOCAL_HOST + ':' + CLI_CONN_PORT);
         }
     }
 
     /**
-     * Spring Application configuration for repository testing in case {@link Ignite} bean with name different from
-     * {@link IgniteProxyFactory#IGNITE_INSTANCE_BEAN_NAME} is used for accessing the cluster.
+     * Spring Application configuration for repository testing in case if Ignite bean name was not provided
+     * through {@link RepositoryConfig#igniteInstance()} ()}.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
-    public static class NonDefaultIgniteBeanApplication {
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+    )
+    public static class DefaultIgniteBeanApplication {
         /** Ignite bean. */
         @Bean
         public Ignite someIgnite() {
@@ -239,12 +248,15 @@
     }
 
     /**
-     * Spring Application configuration for repository testing in case {@link IgniteClient} bean with name different from
-     * {@link IgniteProxyFactory#IGNITE_INSTANCE_BEAN_NAME} is used for accessing the cluster.
+     * Spring Application configuration for repository testing in case if IgniteClient bean name was not provided
+     * through {@link RepositoryConfig#igniteInstance()} ()}.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
-    public static class NonDefaultIgniteClientBeanApplication {
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+    )
+    public static class DefaultIgniteClientBeanApplication {
         /** Ignite client bean. */
         @Bean
         public IgniteClient someIgnite() {
@@ -253,12 +265,15 @@
     }
 
     /**
-     * Spring Application configuration for repository testing in case {@link ClientConfiguration} bean with name different from
-     * {@link IgniteProxyFactory#IGNITE_CONFIG_BEAN_NAME} is used for accessing the cluster.
+     * Spring Application configuration for repository testing in case if ClientConfiguration bean name was not provided
+     * through {@link RepositoryConfig#igniteCfg()}.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
-    public static class NonDefaultIgniteClientConfigurationBeanApplication {
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+    )
+    public static class DefaultIgniteClientConfigurationBeanApplication {
         /** Ignite client configuration bean. */
         @Bean
         public ClientConfiguration someCfg() {
@@ -267,12 +282,15 @@
     }
 
     /**
-     * Spring Application configuration for repository testing in case {@link IgniteConfiguration} bean with name different from
-     * {@link IgniteProxyFactory#IGNITE_CONFIG_BEAN_NAME} is used for accessing the cluster.
+     * Spring Application configuration for repository testing in case if IgniteConfiguration bean name was not provided
+     * through {@link RepositoryConfig#igniteCfg()}.
      */
     @Configuration
-    @EnableIgniteRepositories(includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = PersonRepository.class))
-    public static class NonDefaultIgniteConfigurationBeanApplication {
+    @EnableIgniteRepositories(
+        considerNestedRepositories = true,
+        includeFilters = @Filter(type = ASSIGNABLE_TYPE, classes = IgniteRepositoryWithoutExplicitIgnite.class)
+    )
+    public static class DefaultIgniteConfigurationBeanApplication {
         /** Ignite client configuration bean. */
         @Bean
         public IgniteConfiguration someCfg() {
@@ -280,9 +298,27 @@
         }
     }
 
-    /** Repository for testing application behavior in case the cache name is not specified in the repository configuration. */
-    @RepositoryConfig
-    interface InvalidCacheRepository extends IgniteRepository<Person, Integer> {
+    /** Repository for testing configuration approach through default ignite beans. */
+    @RepositoryConfig(cacheName = "PersonCache")
+    public interface IgniteRepositoryWithoutExplicitIgnite extends IgniteRepository<Object, Serializable> {
+        // No-op.
+    }
+
+    /** Repository for testing configuration approach through {@link IgniteConfiguration}. */
+    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "igniteConfiguration")
+    public interface IgniteConfigRepository extends IgniteRepository<Object, Serializable> {
+        // No-op.
+    }
+
+    /** Repository for testing repository configuration approach through {@link ClientConfiguration}. */
+    @RepositoryConfig(cacheName = "PersonCache", igniteCfg = "clientConfiguration")
+    public interface IgniteClientConfigRepository extends IgniteRepository<Object, Serializable> {
+        // No-op.
+    }
+
+    /** Repository for testing application behavior in case invalid cache is specified in the repository configuration. */
+    @RepositoryConfig(cacheName = "invalidCache", igniteCfg = "igniteConfiguration")
+    public interface InvalidCacheNameRepository extends IgniteRepository<Object, Serializable> {
         // No-op.
     }
 
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfExpressionTest.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
index 3f8cecc..a543044 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataCrudSelfTest.java
@@ -21,55 +21,41 @@
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Optional;
 import java.util.TreeSet;
-import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.processors.query.RunningQueryManager;
-import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
 import org.apache.ignite.springdata.misc.ApplicationConfiguration;
+import org.apache.ignite.springdata.misc.FullNameProjection;
 import org.apache.ignite.springdata.misc.Person;
-import org.apache.ignite.springdata.misc.PersonKey;
+import org.apache.ignite.springdata.misc.PersonProjection;
 import org.apache.ignite.springdata.misc.PersonRepository;
-import org.apache.ignite.springdata.misc.PersonRepositoryWithCompoundKey;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
 /**
  * CRUD tests.
  */
 public class IgniteSpringDataCrudSelfTest extends GridCommonAbstractTest {
-    /** Number of entries to store. */
-    protected static final int CACHE_SIZE = 1000;
+    /** Repository. */
+    protected static PersonRepository repo;
 
     /** Context. */
     protected static AnnotationConfigApplicationContext ctx;
 
-    /** Repository. */
-    protected static PersonRepository repo;
-
-    /** Repository. */
-    protected static PersonRepositoryWithCompoundKey repoWithCompoundKey;
-
-    /** */
-    @Rule
-    public final ExpectedException expected = ExpectedException.none();
-
-    /** */
-    protected static IgniteEx ignite;
+    /** Number of entries to store */
+    private static int CACHE_SIZE = 1000;
 
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
 
         ctx = new AnnotationConfigApplicationContext();
+
         ctx.register(ApplicationConfiguration.class);
+
         ctx.refresh();
 
         repo = ctx.getBean(PersonRepository.class);
-        repoWithCompoundKey = ctx.getBean(PersonRepositoryWithCompoundKey.class);
-        ignite = ctx.getBean(IgniteEx.class);
     }
 
     /** {@inheritDoc} */
@@ -90,8 +76,22 @@
         super.afterTest();
     }
 
+    /** */
+    private void fillInRepository() {
+        for (int i = 0; i < CACHE_SIZE - 5; i++) {
+            repo.save(i, new Person("person" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+        }
+
+        repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
+        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+        repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+    }
+
     /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() {
+    @Override protected void afterTestsStopped() throws Exception {
         ctx.destroy();
     }
 
@@ -104,13 +104,18 @@
 
         assertEquals(person, repo.save(id, person));
 
-        assertTrue(repo.exists(id));
+        assertTrue(repo.existsById(id));
 
-        assertEquals(person, repo.findOne(id));
+        assertEquals(person, repo.findById(id).get());
 
-        expected.expect(UnsupportedOperationException.class);
-        expected.expectMessage("Use IgniteRepository.save(key,value) method instead.");
-        repo.save(person);
+        try {
+            repo.save(person);
+
+            fail("Managed to save a Person without ID");
+        }
+        catch (UnsupportedOperationException e) {
+            //excepted
+        }
     }
 
     /** */
@@ -130,11 +135,16 @@
         while (persons.hasNext())
             assertEquals(origPersons.next(), persons.next());
 
-        expected.expect(UnsupportedOperationException.class);
-        expected.expectMessage("Use IgniteRepository.save(Map<keys,value>) method instead.");
-        repo.save(map.values());
+        try {
+            repo.saveAll(map.values());
 
-        persons = repo.findAll(map.keySet()).iterator();
+            fail("Managed to save a list of Persons with ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
+
+        persons = repo.findAllById(map.keySet()).iterator();
 
         int counter = 0;
 
@@ -168,19 +178,22 @@
     public void testDelete() {
         assertEquals(CACHE_SIZE, repo.count());
 
-        repo.delete(0);
+        repo.deleteById(0);
 
         assertEquals(CACHE_SIZE - 1, repo.count());
-        assertNull(repo.findOne(0));
+        assertEquals(Optional.empty(),repo.findById(0));
 
-        expected.expect(UnsupportedOperationException.class);
-        expected.expectMessage("Use IgniteRepository.delete(key) method instead.");
-        repo.delete(new Person("", ""));
+        try {
+            repo.delete(new Person("", ""));
+
+            fail("Managed to delete a Person without id");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
     }
 
-    /**
-     *
-     */
+    /** */
     @Test
     public void testDeleteSet() {
         assertEquals(CACHE_SIZE, repo.count());
@@ -190,23 +203,26 @@
         for (int i = 0; i < CACHE_SIZE / 2; i++)
             ids.add(i);
 
-        expected.expect(UnsupportedOperationException.class);
-        expected.expectMessage("Use IgniteRepository.deleteAll(keys) method instead.");
-        repo.deleteAll(ids);
+        repo.deleteAllById(ids);
 
         assertEquals(CACHE_SIZE / 2, repo.count());
 
-        ArrayList<Person> persons = new ArrayList<>();
+        try {
+            ArrayList<Person> persons = new ArrayList<>();
 
-        for (int i = 0; i < 3; i++)
-            persons.add(new Person(String.valueOf(i), String.valueOf(i)));
+            for (int i = 0; i < 3; i++)
+                persons.add(new Person(String.valueOf(i), String.valueOf(i)));
 
-        repo.delete(persons);
+            repo.deleteAll(persons);
+
+            fail("Managed to delete Persons without ids");
+        }
+        catch (UnsupportedOperationException e) {
+            //expected
+        }
     }
 
-    /**
-     *
-     */
+    /** */
     @Test
     public void testDeleteAll() {
         assertEquals(CACHE_SIZE, repo.count());
@@ -216,75 +232,216 @@
         assertEquals(0, repo.count());
     }
 
-    /** */
-    private void fillInRepository() {
-        for (int i = 0; i < CACHE_SIZE; i++)
-            repo.save(i, new Person("person" + Integer.toHexString(i),
-                "lastName" + Integer.toHexString((i + 16) % 256)));
-    }
-
-    /** */
+    /**
+     * Delete existing record.
+     */
     @Test
-    public void shouldDeleteAll() {
-        List<PersonKey> ids = prepareDataWithNonComparableKeys();
+    public void testDeleteByFirstName() {
+        assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
 
-        repoWithCompoundKey.deleteAll(ids);
+        long cnt = repo.deleteByFirstName("uniquePerson");
 
-        assertEquals(0, repoWithCompoundKey.count());
+        assertEquals(1, cnt);
     }
 
-    /** */
+    /**
+     * Delete NON existing record.
+     */
     @Test
-    public void shouldFindAll() {
-        List<PersonKey> ids = prepareDataWithNonComparableKeys();
+    public void testDeleteExpression() {
+        long cnt = repo.deleteByFirstName("880");
 
-        Iterable<Person> res = repoWithCompoundKey.findAll(ids);
-
-        assertEquals(2, res.spliterator().estimateSize());
+        assertEquals(0, cnt);
     }
 
-    /** */
-    private List<PersonKey> prepareDataWithNonComparableKeys() {
-        List<PersonKey> ids = new ArrayList<>();
-
-        PersonKey key = new PersonKey(1, 1);
-        ids.add(key);
-
-        repoWithCompoundKey.save(key, new Person("test1", "test1"));
-
-        key = new PersonKey(2, 2);
-        ids.add(key);
-
-        repoWithCompoundKey.save(key, new Person("test2", "test2"));
-
-        assertEquals(2, repoWithCompoundKey.count());
-
-        return ids;
-    }
-
-    /** */
+    /**
+     * Delete Multiple records due to where.
+     */
     @Test
-    public void shouldNotLeakCursorsInRunningQueryManager() {
-        RunningQueryManager runningQryMgr = ((IgniteH2Indexing)ignite.context().query().getIndexing()).runningQueryManager();
+    public void testDeleteExpressionMultiple() {
+        long count = repo.countByFirstName("nonUniquePerson");
+        long cnt = repo.deleteByFirstName("nonUniquePerson");
 
-        assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+        assertEquals(cnt, count);
+    }
 
-        List<Person> res = repo.simpleQuery("person0");
+    /**
+     * Remove should do the same than Delete.
+     */
+    @Test
+    public void testRemoveExpression() {
+        repo.removeByFirstName("person3f");
 
-        assertEquals(1, res.size());
+        long count = repo.count();
+        assertEquals(CACHE_SIZE - 1, count);
+    }
 
-        assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+    /**
+     * Delete unique record using lower case key word.
+     */
+    @Test
+    public void testDeleteQuery() {
+        repo.deleteBySecondNameLowerCase("uniqueLastName");
 
-        Person person = repo.findTopBySecondNameStartingWith("lastName");
+        long countAfter = repo.count();
+        assertEquals(CACHE_SIZE - 1, countAfter);
+    }
 
-        assertNotNull(person);
+    /**
+     * Try to delete with a wrong @Query.
+     */
+    @Test
+    public void testWrongDeleteQuery() {
+        long countBefore = repo.countByFirstNameLike("person3f");
 
-        assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+        try {
+            repo.deleteWrongByFirstNameQuery("person3f");
+        }
+        catch (Exception e) {
+            //expected
+        }
 
-        long cnt = repo.countByFirstName("person0");
+        long countAfter = repo.countByFirstNameLike("person3f");
+        assertEquals(countBefore, countAfter);
+    }
+
+    /**
+     * Update with a @Query a record.
+     */
+    @Test
+    public void testUpdateQueryMixedCase() {
+        final String newSecondName = "updatedUniqueSecondName";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
 
         assertEquals(1, cnt);
 
-        assertEquals(0, runningQryMgr.longRunningQueries(0).size());
+        List<Person> person = repo.findByFirstName("uniquePerson");
+        assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
+    }
+
+    /**
+     * Update with a @Query a record
+     */
+    @Test
+    public void testUpdateQueryMixedCaseProjection() {
+        final String newSecondName = "updatedUniqueSecondName1";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjection("uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName1");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseProjectionNamedParameter() {
+        final String newSecondName = "updatedUniqueSecondName2";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter("uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseDynamicProjectionNamedParameter() {
+        final String newSecondName = "updatedUniqueSecondName2";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+
+        List<FullNameProjection> personFullName = repo.queryByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
+        assertEquals(personFullName.get(0).getFullName(), "uniquePerson updatedUniqueSecondName2");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryOneMixedCaseDynamicProjectionNamedParameter() {
+        final String newSecondName = "updatedUniqueSecondName2";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        PersonProjection person = repo.queryOneByFirstNameWithProjectionNamedParameter(PersonProjection.class, "uniquePerson");
+        assertEquals(person.getFullName(), "uniquePerson updatedUniqueSecondName2");
+
+        FullNameProjection personFullName = repo.queryOneByFirstNameWithProjectionNamedParameter(FullNameProjection.class, "uniquePerson");
+        assertEquals(personFullName.getFullName(), "uniquePerson updatedUniqueSecondName2");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseProjectionIndexedParameter() {
+        final String newSecondName = "updatedUniqueSecondName3";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedIndexedParameter("notUsed","uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName3");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseProjectionIndexedParameterLuceneTextQuery() {
+        final String newSecondName = "updatedUniqueSecondName4";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.textQueryByFirstNameWithProjectionNamedParameter("uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName4");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseProjectionNamedParameterAndTemplateDomainEntityVariable() {
+        final String newSecondName = "updatedUniqueSecondName5";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable("uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName5");
+    }
+
+    /** */
+    @Test
+    public void testUpdateQueryMixedCaseProjectionNamedParameterWithSpELExtension() {
+        final String newSecondName = "updatedUniqueSecondName6";
+        int cnt = repo.setFixedSecondNameMixedCase(newSecondName, "uniquePerson");
+
+        assertEquals(1, cnt);
+
+        List<PersonProjection> person = repo.queryByFirstNameWithProjectionNamedParameterWithSpELExtension("uniquePerson");
+        assertEquals(person.get(0).getFullName(), "uniquePerson updatedUniqueSecondName6");
+        assertEquals(person.get(0).getFirstName(), person.get(0).getFirstNameTransformed());
+    }
+
+    /**
+     * Update with a wrong @Query
+     */
+    @Test
+    public void testWrongUpdateQuery() {
+        final String newSecondName = "updatedUniqueSecondName";
+        int rowsUpdated = 0;
+
+        try {
+            rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
+        }
+        catch (Exception ignored) {
+            //expected
+        }
+
+        assertEquals(0, rowsUpdated);
+
+        List<Person> person = repo.findByFirstName("uniquePerson");
+        assertEquals(person.get(0).getSecondName(), "uniqueLastName");
     }
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
index 39568f9..19a9f63 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/IgniteSpringDataQueriesSelfTest.java
@@ -20,10 +20,13 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import javax.cache.Cache;
 import org.apache.ignite.springdata.misc.ApplicationConfiguration;
 import org.apache.ignite.springdata.misc.Person;
+import org.apache.ignite.springdata.misc.PersonProjection;
 import org.apache.ignite.springdata.misc.PersonRepository;
+import org.apache.ignite.springdata.misc.PersonRepositoryOtherIgniteInstance;
 import org.apache.ignite.springdata.misc.PersonSecondRepository;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
@@ -42,12 +45,22 @@
     /** Repository 2. */
     protected static PersonSecondRepository repo2;
 
+    /**
+     * Repository Ignite Instance cluster TWO.
+     */
+    protected static PersonRepositoryOtherIgniteInstance repoTWO;
+
     /** Context. */
     protected static AnnotationConfigApplicationContext ctx;
 
-    /** Number of entries to store */
+    /**
+     * Number of entries to store
+     */
     protected static int CACHE_SIZE = 1000;
 
+    /**
+     * Performs context initialization before tests.
+     */
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
 
@@ -59,13 +72,20 @@
 
         repo = ctx.getBean(PersonRepository.class);
         repo2 = ctx.getBean(PersonSecondRepository.class);
+        // repository on another ignite instance (and another cluster)
+        repoTWO = ctx.getBean(PersonRepositoryOtherIgniteInstance.class);
 
-        for (int i = 0; i < CACHE_SIZE; i++)
+        for (int i = 0; i < CACHE_SIZE; i++) {
             repo.save(i, new Person("person" + Integer.toHexString(i),
                 "lastName" + Integer.toHexString((i + 16) % 256)));
+            repoTWO.save(i, new Person("TWOperson" + Integer.toHexString(i),
+                "lastName" + Integer.toHexString((i + 16) % 256)));
+        }
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Performs context destroy after tests.
+     */
     @Override protected void afterTestsStopped() throws Exception {
         ctx.destroy();
     }
@@ -83,6 +103,17 @@
 
     /** */
     @Test
+    public void testExplicitQueryTWO() {
+        List<Person> persons = repoTWO.simpleQuery("TWOperson4a");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("TWOperson4a", person.getFirstName());
+    }
+
+    /** */
+    @Test
     public void testEqualsPart() {
         List<Person> persons = repo.findByFirstName("person4e");
 
@@ -94,6 +125,17 @@
 
     /** */
     @Test
+    public void testEqualsPartTWO() {
+        List<Person> persons = repoTWO.findByFirstName("TWOperson4e");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertEquals("TWOperson4e", person.getFirstName());
+    }
+
+    /** */
+    @Test
     public void testContainingPart() {
         List<Person> persons = repo.findByFirstNameContaining("person4");
 
@@ -105,6 +147,17 @@
 
     /** */
     @Test
+    public void testContainingPartTWO() {
+        List<Person> persons = repoTWO.findByFirstNameContaining("TWOperson4");
+
+        assertFalse(persons.isEmpty());
+
+        for (Person person : persons)
+            assertTrue(person.getFirstName().startsWith("TWOperson4"));
+    }
+
+    /** */
+    @Test
     public void testTopPart() {
         Iterable<Person> top = repo.findTopByFirstNameContaining("person4");
 
@@ -119,6 +172,20 @@
 
     /** */
     @Test
+    public void testTopPartTWO() {
+        Iterable<Person> top = repoTWO.findTopByFirstNameContaining("TWOperson4");
+
+        Iterator<Person> iter = top.iterator();
+
+        Person person = iter.next();
+
+        assertFalse(iter.hasNext());
+
+        assertTrue(person.getFirstName().startsWith("TWOperson4"));
+    }
+
+    /** */
+    @Test
     public void testLikeAndLimit() {
         Iterable<Person> like = repo.findFirst10ByFirstNameLike("person");
 
@@ -135,6 +202,22 @@
 
     /** */
     @Test
+    public void testLikeAndLimitTWO() {
+        Iterable<Person> like = repoTWO.findFirst10ByFirstNameLike("TWOperson");
+
+        int cnt = 0;
+
+        for (Person next : like) {
+            assertTrue(next.getFirstName().contains("TWOperson"));
+
+            cnt++;
+        }
+
+        assertEquals(10, cnt);
+    }
+
+    /** */
+    @Test
     public void testCount() {
         int cnt = repo.countByFirstNameLike("person");
 
@@ -143,6 +226,14 @@
 
     /** */
     @Test
+    public void testCountTWO() {
+        int cnt = repoTWO.countByFirstNameLike("TWOperson");
+
+        assertEquals(1000, cnt);
+    }
+
+    /** */
+    @Test
     public void testCount2() {
         int cnt = repo.countByFirstNameLike("person4");
 
@@ -151,8 +242,16 @@
 
     /** */
     @Test
+    public void testCount2TWO() {
+        int cnt = repoTWO.countByFirstNameLike("TWOperson4");
+
+        assertTrue(cnt < 1000);
+    }
+
+    /** */
+    @Test
     public void testPageable() {
-        PageRequest pageable = new PageRequest(1, 5, Sort.Direction.DESC, "firstName");
+        PageRequest pageable = PageRequest.of(1, 5, Sort.Direction.DESC, "firstName");
 
         HashSet<String> firstNames = new HashSet<>();
 
@@ -162,6 +261,7 @@
 
         for (Person person : pageable1) {
             firstNames.add(person.getFirstName());
+
             assertTrue(person.getFirstName().matches("^[a-z]+$"));
         }
 
@@ -171,6 +271,7 @@
 
         for (Person person : pageable2) {
             firstNames.add(person.getFirstName());
+
             assertTrue(person.getFirstName().matches("^[a-z]+$"));
         }
 
@@ -190,7 +291,7 @@
     /** */
     @Test
     public void testQueryWithSort() {
-        List<Person> persons = repo.queryWithSort("^[a-z]+$", new Sort(Sort.Direction.DESC, "secondName"));
+        List<Person> persons = repo.queryWithSort("^[a-z]+$", Sort.by(Sort.Direction.DESC, "secondName"));
 
         Person previous = persons.get(0);
 
@@ -206,7 +307,7 @@
     /** */
     @Test
     public void testQueryWithPaging() {
-        List<Person> persons = repo.queryWithPageable("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+        List<Person> persons = repo.queryWithPageable("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
 
         assertEquals(7, persons.size());
 
@@ -224,7 +325,7 @@
     /** */
     @Test
     public void testQueryFields() {
-        List<String> persons = repo.selectField("^[a-z]+$", new PageRequest(1, 7, Sort.Direction.DESC, "secondName"));
+        List<String> persons = repo.selectField("^[a-z]+$", PageRequest.of(1, 7, Sort.Direction.DESC, "secondName"));
 
         assertEquals(7, persons.size());
     }
@@ -253,17 +354,17 @@
     /** */
     @Test
     public void testFindOneValue() {
-        Person person = repo.findTopBySecondNameStartingWith("lastName18");
+        PersonProjection person = repo.findTopBySecondNameStartingWith("lastName18");
 
         assertNotNull(person);
 
-        assertTrue(person.getSecondName().startsWith("lastName18"));
+        assertTrue(person.getFullName().split("\\s")[1].startsWith("lastName18"));
     }
 
     /** */
     @Test
     public void testSelectSeveralFields() {
-        List<List> lists = repo.selectSeveralField("^[a-z]+$", new PageRequest(2, 6));
+        List<List> lists = repo.selectSeveralField("^[a-z]+$", PageRequest.of(2, 6));
 
         assertEquals(6, lists.size());
 
@@ -285,7 +386,7 @@
     /** */
     @Test
     public void testSliceOfCacheEntries() {
-        Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", new PageRequest(3, 4));
+        Slice<Cache.Entry<Integer, Person>> slice = repo2.findBySecondNameIsNot("lastName18", PageRequest.of(3, 4));
 
         assertEquals(4, slice.getSize());
 
@@ -296,7 +397,7 @@
     /** */
     @Test
     public void testSliceOfLists() {
-        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", new PageRequest(0, 3));
+        Slice<List> lists = repo2.querySliceOfList("^[a-z]+$", PageRequest.of(0, 3));
 
         assertEquals(3, lists.getSize());
 
@@ -307,14 +408,34 @@
         }
     }
 
+    /** Tests conversion of SQL select query result to domain entity objects. */
+    @Test
+    public void testRowToEntityConversion() {
+        Set<Person> res = new HashSet<>(repo.queryWithRowToEntityConversion());
+
+        Set<Person> exp = new HashSet<>();
+
+        repo.findAll().forEach(exp::add);
+
+        assertEquals(exp, res);
+    }
+
     /**
-     * Tests the repository method with a custom query which takes no parameters.
+     * Tests conversion of SQL select query result to domain entity objects if result rows don't contain all fields
+     * of domain entity class.
      */
     @Test
-    public void testCountAllPersons() {
-        int cnt = repo.countAllPersons();
+    public void testIncompleteRowToEntityConversion() {
+        Set<Person> res = new HashSet<>(repo.queryWithIncompleteRowToEntityConversion());
 
-        assertEquals(CACHE_SIZE, cnt);
+        Set<Person> exp = new HashSet<>();
+
+        repo.findAll().forEach(p -> {
+            p.setSecondName(null);
+
+            exp.add(p);
+        });
+
+        assertEquals(exp, res);
     }
 }
-
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
similarity index 100%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityKeyExt.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
index 691fe8e..1100594 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/compoundkey/CityRepository.java
@@ -25,7 +25,7 @@
 
 /** City repository */
 @Repository
-@RepositoryConfig(cacheName = "City")
+@RepositoryConfig(cacheName = "City", autoCreateCache = true)
 public interface CityRepository extends IgniteRepository<City, CityKey> {
     /**
      * Find city by id
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
index ff1045e..075ff1b 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/ApplicationConfiguration.java
@@ -23,28 +23,90 @@
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
 import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.data.spel.spi.EvaluationContextExtension;
 
-/**
- *
- */
+/** */
 @Configuration
 @EnableIgniteRepositories
 public class ApplicationConfiguration {
+    /** */
+    public static final String IGNITE_INSTANCE_ONE = "IGNITE_INSTANCE_ONE";
+
+    /** */
+    public static final String IGNITE_INSTANCE_TWO = "IGNITE_INSTANCE_TWO";
+
     /**
-     * @return Ignite instance.
+     * The bean with cache names
+     */
+    @Bean
+    public CacheNamesBean cacheNames() {
+        CacheNamesBean bean = new CacheNamesBean();
+
+        bean.setPersonCacheName("PersonCache");
+
+        return bean;
+    }
+
+    /** */
+    @Bean
+    public EvaluationContextExtension sampleSpELExtension() {
+        return new SampleEvaluationContextExtension();
+    }
+
+    /** */
+    @Bean(value = "sampleExtensionBean")
+    public SamplePassParamExtension sampleExtensionBean() {
+        return new SamplePassParamExtension();
+    }
+
+    /**
+     * Ignite instance bean - no instance name provided on RepositoryConfig
      */
     @Bean
     public Ignite igniteInstance() {
-        IgniteConfiguration cfg = new IgniteConfiguration()
-            .setCacheConfiguration(
-                new CacheConfiguration<Integer, Person>("PersonCache")
-                    .setIndexedTypes(Integer.class, Person.class),
-                new CacheConfiguration<PersonKey, Person>("PersonWithKeyCache")
-            )
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)));
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setIgniteInstanceName(IGNITE_INSTANCE_ONE);
+
+        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+        ccfg.setIndexedTypes(Integer.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+        cfg.setDiscoverySpi(spi);
+
+        return Ignition.start(cfg);
+    }
+
+    /**
+     * Ignite instance bean with not default name
+     */
+    @Bean
+    public Ignite igniteInstanceTWO() {
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setIgniteInstanceName(IGNITE_INSTANCE_TWO);
+
+        CacheConfiguration ccfg = new CacheConfiguration("PersonCache");
+
+        ccfg.setIndexedTypes(Integer.class, Person.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+        cfg.setDiscoverySpi(spi);
 
         return Ignition.start(cfg);
     }
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/CacheNamesBean.java
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/FullNameProjection.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
index 5044aef..f555e67 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/IgniteClientApplicationConfiguration.java
@@ -20,38 +20,84 @@
 import org.apache.ignite.Ignite;
 import org.apache.ignite.Ignition;
 import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.BinaryConfiguration;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.ClientConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.springdata.misc.SampleEvaluationContextExtension.SamplePassParamExtension;
 import org.apache.ignite.springdata.repository.config.EnableIgniteRepositories;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.data.spel.spi.EvaluationContextExtension;
 
 import static org.apache.ignite.springdata.compoundkey.CompoundKeyApplicationConfiguration.CLI_CONN_PORT;
+import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_ONE;
+import static org.apache.ignite.springdata.misc.ApplicationConfiguration.IGNITE_INSTANCE_TWO;
 
 /** Spring Application configuration for repository testing in case thin client is used for accessing the cluster. */
 @Configuration
 @EnableIgniteRepositories({"org.apache.ignite.springdata.compoundkey", "org.apache.ignite.springdata.misc"})
 public class IgniteClientApplicationConfiguration {
-    /** @return {@link Ignite} node instance. */
-    @Bean
-    public IgniteEx igniteServerNode() {
-        IgniteConfiguration cfg = new IgniteConfiguration()
-            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(CLI_CONN_PORT))
-            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
-            .setCacheConfiguration(new CacheConfiguration<Integer, Person>("PersonCache")
-                .setIndexedTypes(Integer.class, Person.class));
+    /** Test cache name. */
+    public static final String CACHE_NAME = "PersonCache";
 
-        return (IgniteEx)Ignition.start(cfg);
+    /** */
+    @Bean
+    public CacheNamesBean cacheNames() {
+        CacheNamesBean bean = new CacheNamesBean();
+
+        bean.setPersonCacheName(CACHE_NAME);
+
+        return bean;
+    }
+
+    /** */
+    @Bean
+    public EvaluationContextExtension sampleSpELExtension() {
+        return new SampleEvaluationContextExtension();
+    }
+
+    /** */
+    @Bean(value = "sampleExtensionBean")
+    public SamplePassParamExtension sampleExtensionBean() {
+        return new SamplePassParamExtension();
+    }
+
+    /** */
+    @Bean
+    public Ignite igniteServerNode() {
+        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_ONE, CLI_CONN_PORT));
+    }
+
+    /** */
+    @Bean
+    public Ignite igniteSecondServerNode() {
+        return Ignition.start(igniteConfiguration(IGNITE_INSTANCE_TWO, 10801));
     }
 
     /** Ignite client instance bean with default name. */
     @Bean
     public IgniteClient igniteInstance() {
-        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT));
+        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:" + CLI_CONN_PORT)
+            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false)));
+    }
+
+    /** Ignite client instance bean with non-default name. */
+    @Bean
+    public IgniteClient igniteInstanceTWO() {
+        return Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10801"));
+    }
+
+    /** */
+    private static IgniteConfiguration igniteConfiguration(String igniteInstanceName, int cliConnPort) {
+        return new IgniteConfiguration()
+            .setIgniteInstanceName(igniteInstanceName)
+            .setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true)))
+            .setCacheConfiguration(new CacheConfiguration<>(CACHE_NAME).setIndexedTypes(Integer.class, Person.class))
+            .setClientConnectorConfiguration(new ClientConnectorConfiguration().setPort(cliConnPort))
+            .setBinaryConfiguration(new BinaryConfiguration().setCompactFooter(false));
     }
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
index 154937f..62c3054 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/Person.java
@@ -17,8 +17,10 @@
 
 package org.apache.ignite.springdata.misc;
 
+import java.util.Date;
 import java.util.Objects;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
 
 /**
  * DTO class.
@@ -26,12 +28,17 @@
 public class Person {
     /** First name. */
     @QuerySqlField(index = true)
+    @QueryTextField
     private String firstName;
 
     /** Second name. */
     @QuerySqlField(index = true)
     private String secondName;
 
+    /** Birthday. */
+    @QuerySqlField
+    private Date birthday;
+
     /**
      * @param firstName First name.
      * @param secondName Second name.
@@ -39,6 +46,7 @@
     public Person(String firstName, String secondName) {
         this.firstName = firstName;
         this.secondName = secondName;
+        birthday = new Date();
     }
 
     /**
@@ -74,6 +82,7 @@
         return "Person{" +
             "firstName='" + firstName + '\'' +
             ", secondName='" + secondName + '\'' +
+            ", birthday='" + birthday + '\'' +
             '}';
     }
 
@@ -88,11 +97,12 @@
         Person person = (Person)o;
 
         return Objects.equals(firstName, person.firstName) &&
-            Objects.equals(secondName, person.secondName);
+            Objects.equals(secondName, person.secondName) &&
+            Objects.equals(birthday, person.birthday);
     }
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        return Objects.hash(firstName, secondName);
+        return Objects.hash(firstName, secondName, birthday);
     }
 }
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
similarity index 87%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
index 8222eb3..4c5e0ca 100644
--- a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonExpressionRepository.java
@@ -17,8 +17,8 @@
 
 package org.apache.ignite.springdata.misc;
 
-import org.apache.ignite.springdata20.repository.IgniteRepository;
-import org.apache.ignite.springdata20.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 
 /**
  *
diff --git a/modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
similarity index 100%
rename from modules/spring-data-2.0-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonProjection.java
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
index d8444d1..4cb959d 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepository.java
@@ -20,12 +20,14 @@
 
 import java.util.Collection;
 import java.util.List;
+
 import javax.cache.Cache;
 import org.apache.ignite.springdata.repository.IgniteRepository;
 import org.apache.ignite.springdata.repository.config.Query;
 import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
+import org.springframework.data.repository.query.Param;
 
 /**
  * Test repository.
@@ -36,6 +38,36 @@
     public List<Person> findByFirstName(String val);
 
     /** */
+    @Query("firstName = ?")
+    public List<PersonProjection> queryByFirstNameWithProjection(String val);
+
+    /** */
+    @Query("firstName = :firstname")
+    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
+
+    /** */
+    @Query("firstName = :firstname")
+    public <P> List<P> queryByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
+
+    /** */
+    @Query("firstName = :firstname")
+    public <P> P queryOneByFirstNameWithProjectionNamedParameter(Class<P> dynamicProjection, @Param("firstname") String val);
+
+    /** */
+    @Query("firstName = ?#{[1]}")
+    public List<PersonProjection> queryByFirstNameWithProjectionNamedIndexedParameter(@Param("notUsed") String notUsed, @Param("firstname") String val);
+
+    /** */
+    @Query(textQuery = true, value = "#{#firstname}", limit = 2)
+    public List<PersonProjection> textQueryByFirstNameWithProjectionNamedParameter(@Param("firstname") String val);
+
+    @Query(value = "select * from (sElecT * from #{#entityName} where firstName = :firstname)", forceFieldsQuery = true)
+    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterAndTemplateDomainEntityVariable(@Param("firstname") String val);
+
+    @Query(value = "firstName = ?#{sampleExtension.transformParam(#firstname)}")
+    public List<PersonProjection> queryByFirstNameWithProjectionNamedParameterWithSpELExtension(@Param("firstname") String val);
+
+    /** */
     public List<Person> findByFirstNameContaining(String val);
 
     /** */
@@ -66,7 +98,7 @@
     public Cache.Entry<Integer, Person> findTopBySecondNameLike(String val);
 
     /** */
-    public Person findTopBySecondNameStartingWith(String val);
+    public PersonProjection findTopBySecondNameStartingWith(String val);
 
     /** */
     @Query("firstName = ?")
@@ -92,8 +124,36 @@
     @Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
     public int countQuery(String val);
 
-    /** */
-    @Query("SELECT count(*) FROM Person")
-    public int countAllPersons();
-}
+    /** Top 3 query */
+    public List<Person> findTop3ByFirstName(String val);
 
+    /** Delete query */
+    public long deleteByFirstName(String firstName);
+
+    /** Remove Query */
+    public List<Person> removeByFirstName(String firstName);
+
+    /** Delete using @Query with keyword in lower-case */
+    @Query("delete FROM Person WHERE secondName = ?")
+    public void deleteBySecondNameLowerCase(String secondName);
+
+    /** Delete using @Query but with errors on the query */
+    @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
+    public void deleteWrongByFirstNameQuery(String firstName);
+
+    /** Update using @Query with keyword in mixed-case */
+    @Query("upDATE Person SET secondName = ? WHERE firstName = ?")
+    public int setFixedSecondNameMixedCase(String secondName, String firstName);
+
+    /** Update using @Query but with errors on the query */
+    @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
+    public int setWrongFixedSecondName(String secondName, String firstName);
+
+    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
+    @Query(value = "SELECT firstName, secondName, birthday, _key, _val, NULL as one FROM Person", forceFieldsQuery = true)
+    public List<Person> queryWithRowToEntityConversion();
+
+    /** Produces a list of domain entity classes whose fields are obtained from the query result row. */
+    @Query(value = "SELECT firstName, birthday FROM Person", forceFieldsQuery = true)
+    public List<Person> queryWithIncompleteRowToEntityConversion();
+}
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
similarity index 96%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
index 307556b..47d2aa9 100644
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryOtherIgniteInstance.java
@@ -22,9 +22,9 @@
 import java.util.List;
 
 import javax.cache.Cache;
-import org.apache.ignite.springdata22.repository.IgniteRepository;
-import org.apache.ignite.springdata22.repository.config.Query;
-import org.apache.ignite.springdata22.repository.config.RepositoryConfig;
+import org.apache.ignite.springdata.repository.IgniteRepository;
+import org.apache.ignite.springdata.repository.config.Query;
+import org.apache.ignite.springdata.repository.config.RepositoryConfig;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.repository.query.Param;
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
index e868911..062303c 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonRepositoryWithCompoundKey.java
@@ -23,6 +23,6 @@
 /**
  * Test repository.
  */
-@RepositoryConfig(cacheName = "PersonWithKeyCache")
+@RepositoryConfig(cacheName = "PersonWithKeyCache", autoCreateCache = true)
 public interface PersonRepositoryWithCompoundKey extends IgniteRepository<Person, PersonKey> {
 }
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
index a82e822..b2b70ec 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/PersonSecondRepository.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.springdata.misc;
 
 import java.util.List;
+
 import javax.cache.Cache;
 import org.apache.ignite.springdata.repository.IgniteRepository;
 import org.apache.ignite.springdata.repository.config.Query;
@@ -27,7 +28,7 @@
 import org.springframework.data.domain.Slice;
 
 /**
- *
+ * Test repository.
  */
 @RepositoryConfig(cacheName = "PersonCache")
 public interface PersonSecondRepository extends IgniteRepository<Person, Integer> {
diff --git a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
similarity index 97%
rename from modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
rename to modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
index 9db4343..0c54b41 100644
--- a/modules/spring-data-2.2-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/springdata/misc/SampleEvaluationContextExtension.java
@@ -22,7 +22,7 @@
 import org.springframework.data.spel.spi.EvaluationContextExtension;
 
 /**
- * Sample EvaluationContext Extension for Spring Data 2.2
+ * Sample EvaluationContext Extension for Spring Data.
  * <p>
  * Use SpEl expressions into your {@code @Query} definitions.
  * <p>
diff --git a/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java b/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
index 4a47568..5eb926e 100644
--- a/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
+++ b/modules/spring-data-ext/src/test/java/org/apache/ignite/testsuites/IgniteSpringDataTestSuite.java
@@ -20,8 +20,10 @@
 import org.apache.ignite.springdata.IgniteClientSpringDataCompoundKeyTest;
 import org.apache.ignite.springdata.IgniteClientSpringDataCrudSelfTest;
 import org.apache.ignite.springdata.IgniteClientSpringDataQueriesSelfTest;
+import org.apache.ignite.springdata.IgniteSpringDataCompoundExtendedKeyTest;
 import org.apache.ignite.springdata.IgniteSpringDataCompoundKeyTest;
 import org.apache.ignite.springdata.IgniteSpringDataConnectionConfigurationTest;
+import org.apache.ignite.springdata.IgniteSpringDataCrudSelfExpressionTest;
 import org.apache.ignite.springdata.IgniteSpringDataCrudSelfTest;
 import org.apache.ignite.springdata.IgniteSpringDataQueriesSelfTest;
 import org.junit.runner.RunWith;
@@ -34,7 +36,9 @@
 @Suite.SuiteClasses({
     IgniteSpringDataCrudSelfTest.class,
     IgniteSpringDataQueriesSelfTest.class,
+    IgniteSpringDataCrudSelfExpressionTest.class,
     IgniteSpringDataCompoundKeyTest.class,
+    IgniteSpringDataCompoundExtendedKeyTest.class,
     IgniteSpringDataConnectionConfigurationTest.class,
     IgniteClientSpringDataCrudSelfTest.class,
     IgniteClientSpringDataQueriesSelfTest.class,
@@ -42,4 +46,3 @@
 })
 public class IgniteSpringDataTestSuite {
 }
-
diff --git a/modules/spring-session-ext/pom.xml b/modules/spring-session-ext/pom.xml
index d0cb2c7..1a3b8b7 100644
--- a/modules/spring-session-ext/pom.xml
+++ b/modules/spring-session-ext/pom.xml
@@ -34,7 +34,6 @@
     <url>http://ignite.apache.org</url>
 
     <properties>
-        <spring.version>5.3.8</spring.version>
         <spring.session.version>2.5.0</spring.session.version>
         <spring.security.version>5.5.0</spring.security.version>
         <javax.annotation.version>1.3.2</javax.annotation.version>
@@ -53,15 +52,22 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-spring</artifactId>
+            <version>${ignite.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-expression</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
@@ -82,7 +88,7 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
         </dependency>
 
         <dependency>
@@ -111,7 +117,7 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
             <scope>test</scope>
         </dependency>
 
@@ -126,7 +132,7 @@
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
-            <version>${spring.version}</version>
+            <version>${spring53.version}</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/org.apache.ignite/ignite-indexing -->
diff --git a/parent/pom.xml b/parent/pom.xml
index ad06205..56a1eb3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -41,10 +41,8 @@
         <ignite-spring-boot-autoconfigure-ext.version>1.1.0-SNAPSHOT</ignite-spring-boot-autoconfigure-ext.version>
         <ignite-spring-boot-thin-client-autoconfigure-ext.version>1.1.0-SNAPSHOT</ignite-spring-boot-thin-client-autoconfigure-ext.version>
         <ignite-spring-cache-ext.version>1.1.0-SNAPSHOT</ignite-spring-cache-ext.version>
-        <ignite-spring-data-2.0-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-2.0-ext.version>
-        <ignite-spring-data-2.2-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-2.2-ext.version>
+        <ignite-spring-data-ext.version>2.0.0-SNAPSHOT</ignite-spring-data-ext.version>
         <ignite-spring-data-commons.version>1.2.0-SNAPSHOT</ignite-spring-data-commons.version>
-        <ignite-spring-data-ext.version>1.1.0-SNAPSHOT</ignite-spring-data-ext.version>
         <ignite-spring-tx-ext.version>1.1.0-SNAPSHOT</ignite-spring-tx-ext.version>
         <ignite-zookeeper-ip-finder-ext.version>1.0.0-SNAPSHOT</ignite-zookeeper-ip-finder-ext.version>
 
@@ -134,14 +132,10 @@
         <snappy.version>1.1.7.2</snappy.version>
         <spark.hadoop.version>2.6.5</spark.hadoop.version>
         <spark.version>2.3.0</spark.version>
-        <spring.data.version>1.13.23.RELEASE</spring.data.version> <!-- don't forget to update spring version -->
-        <spring.version>4.3.26.RELEASE</spring.version><!-- don't forget to update spring-data version -->
-        <spring.data-2.0.version>2.0.13.RELEASE</spring.data-2.0.version> <!-- don't forget to update spring-5.0 version -->
-        <spring-5.0.version>5.0.16.RELEASE</spring-5.0.version><!-- don't forget to update spring-data-2.0 version -->
-        <spring.data-2.2.version>2.2.3.RELEASE</spring.data-2.2.version> <!-- don't forget to update spring-5.2 version -->
-        <spring-5.2.version>5.2.3.RELEASE</spring-5.2.version><!-- don't forget to update spring-data-2.2 version -->
-        <spring41.osgi.feature.version>4.1.7.RELEASE_1</spring41.osgi.feature.version>
-        <spring-boot.version>2.2.2.RELEASE</spring-boot.version>
+        <spring.version>5.2.21.RELEASE</spring.version><!-- don't forget to update spring-data version -->
+        <spring.data.version>2.2.13.RELEASE</spring.data.version> <!-- don't forget to update spring version -->
+        <spring-boot.version>2.2.13.RELEASE</spring-boot.version>
+        <spring53.version>5.3.19</spring53.version>
         <storm.version>1.1.1</storm.version>
         <tomcat.version>9.0.10</tomcat.version>
         <twitter.hbc.version>2.2.0</twitter.hbc.version>
@@ -354,14 +348,6 @@
                                 <packages>org.apache.ignite.springdata.repository*</packages>
                             </group>
                             <group>
-                                <title>SpringData 2.0 integration</title>
-                                <packages>org.apache.ignite.springdata20.repository*</packages>
-                            </group>
-                            <group>
-                                <title>SpringData 2.2 integration</title>
-                                <packages>org.apache.ignite.springdata22.repository*</packages>
-                            </group>
-                            <group>
                             <title>RocketMQ integration</title>
                                 <packages>org.apache.ignite.stream.rocketmq*</packages>
                             </group>
diff --git a/pom.xml b/pom.xml
index 2d2899c..e0531a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,8 +57,6 @@
         <module>modules/jms11-ext</module>
         <module>modules/kafka-ext</module>
         <module>modules/spring-data-ext</module>
-        <module>modules/spring-data-2.0-ext</module>
-        <module>modules/spring-data-2.2-ext</module>
         <module>modules/spring-data-commons</module>
         <module>modules/performance-statistics-ext</module>
         <module>modules/spring-tx-ext</module>
@@ -85,8 +83,7 @@
             <modules>
                 <module>modules/spring-boot-autoconfigure-ext/examples</module>
                 <module>modules/spring-boot-thin-client-autoconfigure-ext/examples</module>
-                <module>modules/spring-data-2.0-ext/examples</module>
-                <module>modules/spring-data-2.2-ext/examples</module>
+                <module>modules/spring-data-ext/examples</module>
                 <module>modules/spring-tx-ext/examples</module>
                 <module>modules/zookeeper-ip-finder-ext/examples</module>
             </modules>
@@ -157,18 +154,6 @@
                                 </goals>
                                 <phase>validate</phase>
                                 <configuration>
-                                    <additionalDependencies>
-                                        <!--
-                                        Only the last version of spring data is included to class path, some classes
-                                        required by old spring data modules are absent in this version.
-                                        Add spring-data-2.0 explicitly to be able to find all required classes.
-                                        -->
-                                        <dependency>
-                                            <groupId>org.springframework.data</groupId>
-                                            <artifactId>spring-data-commons</artifactId>
-                                            <version>${spring.data-2.0.version}</version>
-                                        </dependency>
-                                    </additionalDependencies>
                                     <reportOutputDirectory>${basedir}/target/javadoc</reportOutputDirectory>
                                     <destDir>core</destDir>
                                     <subpackages>org.apache.ignite -exclude org.apache.ignite.codegen:org.apache.ignite.examples:org.apache.ignite.internal:org.apache.ignite.schema:org.apache.ignite.tests:org.apache.ignite.tools:org.apache.ignite.util:org.apache.ignite.spi.discovery.tcp.messages:org.apache.ignite.spi.discovery.tcp.internal:org.apache.ignite.spi.communication.tcp.internal:org.apache.ignite.spi.discovery.zk.internal:org.apache.ignite.spi.deployment.uri.scanners:org.apache.ignite.spi.deployment.uri.tasks:org.apache.ignite.yardstick:org.apache.ignite.webtest</subpackages>