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

[03/24] incubator-ignite git commit: ignite-545: merge from ignite-sprint-6

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/IgniteTask.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/IgniteTask.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/IgniteTask.java
new file mode 100644
index 0000000..ecd2272
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/IgniteTask.java
@@ -0,0 +1,86 @@
+/*
+ * 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.mesos;
+
+/**
+ * Information about launched task.
+ */
+public class IgniteTask {
+    /** */
+    public final String host;
+
+    /** */
+    public final double cpuCores;
+
+    /** */
+    public final double mem;
+
+    /** */
+    public final double disk;
+
+    /**
+     * Ignite launched task.
+     *
+     * @param host Host.
+     * @param cpuCores Cpu cores count.
+     * @param mem Memory.
+     * @param disk Disk.
+     */
+    public IgniteTask(String host, double cpuCores, double mem, double disk) {
+        this.host = host;
+        this.cpuCores = cpuCores;
+        this.mem = mem;
+        this.disk = disk;
+    }
+
+    /**
+     * @return Host.
+     */
+    public String host() {
+        return host;
+    }
+
+    /**
+     * @return Cores count.
+     */
+    public double cpuCores() {
+        return cpuCores;
+    }
+
+    /**
+     * @return Memory.
+     */
+    public double mem() {
+        return mem;
+    }
+
+    /**
+     * @return Disk.
+     */
+    public double disk() {
+        return disk;
+    }
+
+    @Override
+    public String toString() {
+        return "IgniteTask " +
+            "host: [" + host + ']' +
+            ", cpuCores: [" + cpuCores + "]" +
+            ", mem: [" + mem + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/package-info.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/package-info.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/package-info.java
new file mode 100644
index 0000000..0404c02
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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. -->
+ * Contains classes to support integration with Apache Mesos.
+ */
+package org.apache.ignite.mesos;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/IgniteProvider.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/IgniteProvider.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/IgniteProvider.java
new file mode 100644
index 0000000..f459e5d
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/IgniteProvider.java
@@ -0,0 +1,234 @@
+/*
+ * 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.mesos.resource;
+
+import java.io.*;
+import java.net.*;
+import java.nio.channels.*;
+import java.util.*;
+
+/**
+ * Class downloads and stores Ignite.
+ */
+public class IgniteProvider {
+    /** */
+    public static final String DOWNLOAD_LINK = "http://tiny.cc/updater/download_community.php";
+
+    /** */
+    public static final String DIRECT_DOWNLOAD_LINK = "http://www.gridgain.com/media/gridgain-community-fabric-";
+
+    /** */
+    private String downloadFolder;
+
+    /** */
+    private String latestVersion = null;
+
+    /**
+     * @param downloadFolder Folder with ignite.
+     */
+    public IgniteProvider(String downloadFolder) {
+        this.downloadFolder = downloadFolder;
+    }
+
+    /**
+     * @return Latest ignite version.
+     */
+    public String getIgnite() {
+        File folder = checkDownloadFolder();
+
+        if (latestVersion == null) {
+            List<String> files = findIgnites(folder);
+
+            if (!files.isEmpty()) {
+                if (files.size() == 1)
+                    latestVersion = parseVersion(files.get(0));
+                else
+                    latestVersion = parseVersion(Collections.max(files, new Comparator<String>() {
+                        @Override public int compare(String f1, String f2) {
+                            if (f1.equals(f2))
+                                return 0;
+
+                            String[] ver1 = parseVersion(f1).split("\\.");
+                            String[] ver2 = parseVersion(f2).split("\\.");
+
+                            if (Integer.valueOf(ver1[0]) >= Integer.valueOf(ver2[0])
+                                && Integer.valueOf(ver1[1]) >= Integer.valueOf(ver2[1])
+                                && Integer.valueOf(ver1[2]) >= Integer.valueOf(ver2[2]))
+
+                                return 1;
+                            else
+                                return -1;
+                        }
+                    }));
+            }
+        }
+
+        latestVersion = updateIgnite(latestVersion);
+
+        return "gridgain-community-fabric-" + latestVersion + ".zip";
+    }
+
+    /**
+     * @param folder Folder.
+     * @return Ignite archives.
+     */
+    private List<String> findIgnites(File folder) {
+        String[] files = folder.list();
+
+        List<String> ignites = new ArrayList<>();
+
+        if (files != null) {
+            for (String fileName : files) {
+                if (fileName.contains("gridgain-community-fabric-") && fileName.endsWith(".zip"))
+                    ignites.add(fileName);
+            }
+        }
+
+        return ignites;
+    }
+
+    /**
+     * @param version Ignite version.
+     * @return Ignite.
+     */
+    public String getIgnite(String version) {
+        File folder = checkDownloadFolder();
+
+        String[] ignites = folder.list();
+
+        String ignite = null;
+
+        if (ignites != null) {
+            for (String fileName : ignites) {
+                if (fileName.equals("gridgain-community-fabric-" + version + ".zip"))
+                    ignite = fileName;
+            }
+        }
+
+        if (ignite != null)
+            return ignite;
+
+        return downloadIgnite(version);
+    }
+
+    /**
+     * @param currentVersion The current latest version.
+     * @return Current version if the current version is latest; new ignite version otherwise.
+     */
+    private String updateIgnite(String currentVersion) {
+        try {
+            URL url;
+
+            if (currentVersion == null)
+                url = new URL(DOWNLOAD_LINK);
+            else
+                url = new URL(DOWNLOAD_LINK + "?version=" + currentVersion);
+
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+
+            int code = conn.getResponseCode();
+
+            if (code == 200) {
+                String redirectUrl = conn.getURL().toString();
+
+                checkDownloadFolder();
+
+                FileOutputStream outFile = new FileOutputStream(downloadFolder + "/" + fileName(redirectUrl));
+
+                outFile.getChannel().transferFrom(Channels.newChannel(conn.getInputStream()), 0, Long.MAX_VALUE);
+
+                outFile.close();
+
+                return parseVersion(redirectUrl);
+            }
+            else if (code == 304)
+                // This version is latest.
+                return currentVersion;
+            else
+                throw new RuntimeException("Got unexpected response code. Response code: " + code);
+        }
+        catch (IOException e) {
+            throw new RuntimeException("Failed update ignite.", e);
+        }
+    }
+
+    /**
+     * @param version The current latest version.
+     * @return Ignite archive.
+     */
+    public String downloadIgnite(String version) {
+        try {
+            URL url = new URL(DIRECT_DOWNLOAD_LINK + version + ".zip");
+
+            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
+
+            int code = conn.getResponseCode();
+
+            if (code == 200) {
+                checkDownloadFolder();
+
+                String fileName = fileName(url.toString());
+
+                FileOutputStream outFile = new FileOutputStream(downloadFolder + fileName);
+
+                outFile.getChannel().transferFrom(Channels.newChannel(conn.getInputStream()), 0, Long.MAX_VALUE);
+
+                outFile.close();
+
+                return fileName;
+            }
+            else
+                throw new RuntimeException("Got unexpected response code. Response code: " + code);
+        }
+        catch (IOException e) {
+            throw new RuntimeException("Failed update ignite.", e);
+        }
+    }
+
+    /**
+     * @return Download folder.
+     */
+    private File checkDownloadFolder() {
+        File file = new File(downloadFolder);
+
+        if (!file.exists())
+            file.mkdirs();
+
+        return file;
+    }
+
+    /**
+     * @param url URL.
+     * @return Ignite version.
+     */
+    public static String parseVersion(String url) {
+        String[] split = url.split("-");
+
+        return split[split.length - 1].replaceAll(".zip", "");
+    }
+
+    /**
+     * @param url URL.
+     * @return File name.
+     */
+    private static String fileName(String url) {
+        String[] split = url.split("/");
+
+        return split[split.length - 1];
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/JettyServer.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/JettyServer.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/JettyServer.java
new file mode 100644
index 0000000..446ac77
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/JettyServer.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.mesos.resource;
+
+import org.eclipse.jetty.server.*;
+
+import java.net.*;
+
+/**
+ * Embedded jetty server.
+ */
+public class JettyServer {
+    /** */
+    private Server server;
+
+    /**
+     * Starts jetty server.
+     *
+     * @param address Inter socket address.
+     * @param handler Handler.
+     * @throws Exception If failed.
+     */
+    public void start(InetSocketAddress address, Handler handler) throws Exception {
+        if (server == null) {
+            server = new Server(address);
+
+            server.setHandler(handler);
+
+            server.start();
+        }
+        else
+            throw new IllegalStateException("Jetty server has already been started.");
+    }
+
+    /**
+     * Stops server.
+     *
+     * @throws Exception If failed.
+     */
+    public void stop() throws Exception {
+        if (server != null)
+            server.stop();
+        else
+            throw new IllegalStateException("Jetty server has not yet been started.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceHandler.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceHandler.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceHandler.java
new file mode 100644
index 0000000..cb8c773
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceHandler.java
@@ -0,0 +1,142 @@
+/*
+ * 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.mesos.resource;
+
+import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.server.handler.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+
+/**
+ * HTTP controller which provides on slave resources.
+ */
+public class ResourceHandler extends AbstractHandler {
+    /** */
+    public static final String IGNITE_PREFIX = "/ignite/";
+
+    /** */
+    public static final String LIBS_PREFIX = "/libs/";
+
+    /** */
+    public static final String CONFIG_PREFIX = "/config/";
+
+    /** */
+    public static final String DEFAULT_CONFIG = CONFIG_PREFIX + "default/";
+
+    /** */
+    private String libsDir;
+
+    /** */
+    private String cfgPath;
+
+    /** */
+    private String igniteDir;
+
+    /**
+     * @param libsDir Directory with user's libs.
+     * @param cfgPath Path to config file.
+     * @param igniteDir Directory with ignites.
+     */
+    public ResourceHandler(String libsDir, String cfgPath, String igniteDir) {
+        this.libsDir = libsDir;
+        this.cfgPath = cfgPath;
+        this.igniteDir = igniteDir;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public void handle(
+        String url,
+        Request request,
+        HttpServletRequest httpServletRequest,
+        HttpServletResponse response) throws IOException, ServletException {
+
+        String[] path = url.split("/");
+
+        String fileName = path[path.length - 1];
+
+        String servicePath = url.substring(0, url.length() - fileName.length());
+
+        switch (servicePath) {
+            case IGNITE_PREFIX:
+                handleRequest(response, "application/zip-archive", igniteDir + "/" + fileName);
+
+                request.setHandled(true);
+                break;
+
+            case LIBS_PREFIX:
+                handleRequest(response, "application/java-archive", libsDir + "/" + fileName);
+
+                request.setHandled(true);
+                break;
+
+            case CONFIG_PREFIX:
+                handleRequest(response, "application/xml", cfgPath);
+
+                request.setHandled(true);
+                break;
+
+            case DEFAULT_CONFIG:
+                handleRequest(response, "application/xml",
+                    Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName),
+                    fileName);
+
+                request.setHandled(true);
+                break;
+        }
+    }
+
+    /**
+     * @param response Http response.
+     * @param type Type.
+     * @param path Path to file.
+     * @throws IOException If failed.
+     */
+    private static void handleRequest(HttpServletResponse response, String type, String path) throws IOException {
+        Path path0 = Paths.get(path);
+
+        response.setContentType(type);
+        response.setHeader("Content-Disposition", "attachment; filename=\"" + path0.getFileName() + "\"");
+
+        try (HttpOutput out = (HttpOutput)response.getOutputStream()) {
+            out.sendContent(FileChannel.open(path0, StandardOpenOption.READ));
+        }
+    }
+
+    /**
+     * @param response Http response.
+     * @param type Type.
+     * @param stream Stream.
+     * @param attachmentName Attachment name.
+     * @throws IOException If failed.
+     */
+    private static void handleRequest(HttpServletResponse response, String type, InputStream stream,
+        String attachmentName) throws IOException {
+        response.setContentType(type);
+        response.setHeader("Content-Disposition", "attachment; filename=\"" + attachmentName + "\"");
+
+        try (HttpOutput out = (HttpOutput)response.getOutputStream()) {
+            out.sendContent(stream);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceProvider.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceProvider.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceProvider.java
new file mode 100644
index 0000000..f02d1bf
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/ResourceProvider.java
@@ -0,0 +1,120 @@
+/*
+ * 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.mesos.resource;
+
+import org.apache.ignite.mesos.*;
+
+import java.io.*;
+import java.util.*;
+
+import static org.apache.ignite.mesos.resource.ResourceHandler.*;
+
+/**
+ * Provides path to user's libs and config file.
+ */
+public class ResourceProvider {
+    /** Ignite url. */
+    private String igniteUrl;
+
+    /** Resources. */
+    private Collection<String> libsUris;
+
+    /** Url config. */
+    private String configUrl;
+
+    /** Config name. */
+    private String configName;
+
+    /**
+     * @param properties Cluster properties.
+     * @param provider Ignite provider.
+     * @param baseUrl Base url.
+     */
+    public void init(ClusterProperties properties, IgniteProvider provider, String baseUrl) {
+        // Downloading ignite.
+        if (properties.igniteVer().equals(ClusterProperties.DEFAULT_IGNITE_VERSION))
+            igniteUrl = baseUrl + IGNITE_PREFIX + provider.getIgnite();
+        else
+            igniteUrl = baseUrl + IGNITE_PREFIX + provider.getIgnite(properties.igniteVer());
+
+        // Find all jar files into user folder.
+        if (properties.userLibs() != null && !properties.userLibs().isEmpty()) {
+            File libsDir = new File(properties.userLibs());
+
+            List<String> libs = new ArrayList<>();
+
+            if (libsDir.isDirectory()) {
+                File[] files = libsDir.listFiles();
+
+                if (files != null) {
+                    for (File lib : files) {
+                        if (lib.isFile() && lib.canRead() &&
+                            (lib.getName().endsWith(".jar") || lib.getName().endsWith(".JAR")))
+                            libs.add(baseUrl + LIBS_PREFIX + lib.getName());
+                    }
+                }
+            }
+
+            libsUris = libs.isEmpty() ? null : libs;
+        }
+
+        // Set configuration url.
+        if (properties.igniteCfg() != null) {
+            File cfg = new File(properties.igniteCfg());
+
+            if (cfg.isFile() && cfg.canRead()) {
+                configUrl = baseUrl + CONFIG_PREFIX + cfg.getName();
+
+                configName = cfg.getName();
+            }
+        }
+        else {
+            configName = "ignite-default-config.xml";
+
+            configUrl = baseUrl + DEFAULT_CONFIG + configName;
+        }
+    }
+
+    /**
+     * @return Config name.
+     */
+    public String configName() {
+        return configName;
+    }
+
+    /**
+     * @return Ignite url.
+     */
+    public String igniteUrl() {
+        return igniteUrl;
+    }
+
+    /**
+     * @return Urls to user's libs.
+     */
+    public Collection<String> resourceUrl() {
+        return libsUris;
+    }
+
+    /**
+     * @return Url to config file.
+     */
+    public String igniteConfigUrl() {
+        return configUrl;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/package-info.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/package-info.java b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/package-info.java
new file mode 100644
index 0000000..7e3614e
--- /dev/null
+++ b/modules/mesos/src/main/java/org/apache/ignite/mesos/resource/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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. -->
+ * Contains classes provide access to resources.
+ */
+package org.apache.ignite.mesos.resource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/main/resources/ignite-default-config.xml
----------------------------------------------------------------------
diff --git a/modules/mesos/src/main/resources/ignite-default-config.xml b/modules/mesos/src/main/resources/ignite-default-config.xml
new file mode 100644
index 0000000..2f26398
--- /dev/null
+++ b/modules/mesos/src/main/resources/ignite-default-config.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                            http://www.springframework.org/schema/beans/spring-beans.xsd">
+    <bean class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"/>
+                </property>
+
+                <property name="joinTimeout" value="60000"/>
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/test/java/org/apache/ignite/IgniteMesosTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/test/java/org/apache/ignite/IgniteMesosTestSuite.java b/modules/mesos/src/test/java/org/apache/ignite/IgniteMesosTestSuite.java
new file mode 100644
index 0000000..f1bcb90
--- /dev/null
+++ b/modules/mesos/src/test/java/org/apache/ignite/IgniteMesosTestSuite.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+import junit.framework.*;
+import org.apache.ignite.mesos.*;
+
+/**
+ * Apache Mesos integration tests.
+ */
+public class IgniteMesosTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Apache Mesos Integration Test Suite");
+
+        suite.addTest(new TestSuite(IgniteSchedulerSelfTest.class));
+
+        return suite;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/mesos/src/test/java/org/apache/ignite/mesos/IgniteSchedulerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/mesos/src/test/java/org/apache/ignite/mesos/IgniteSchedulerSelfTest.java b/modules/mesos/src/test/java/org/apache/ignite/mesos/IgniteSchedulerSelfTest.java
new file mode 100644
index 0000000..d627553
--- /dev/null
+++ b/modules/mesos/src/test/java/org/apache/ignite/mesos/IgniteSchedulerSelfTest.java
@@ -0,0 +1,464 @@
+/*
+ * 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.mesos;
+
+import junit.framework.*;
+import org.apache.ignite.mesos.resource.*;
+import org.apache.mesos.*;
+
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ * Scheduler tests.
+ */
+public class IgniteSchedulerSelfTest extends TestCase {
+    /** */
+    private IgniteScheduler scheduler;
+
+    /** {@inheritDoc} */
+    @Override public void setUp() throws Exception {
+        super.setUp();
+
+        ClusterProperties clustProp = new ClusterProperties();
+
+        scheduler = new IgniteScheduler(clustProp, new ResourceProvider() {
+            @Override public String configName() {
+                return "config.xml";
+            }
+
+            @Override public String igniteUrl() {
+                return "ignite.jar";
+            }
+
+            @Override public String igniteConfigUrl() {
+                return "config.xml";
+            }
+
+            @Override public Collection<String> resourceUrl() {
+                return null;
+            }
+        });
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testHostRegister() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 4, 1024);
+
+        DriverMock mock = new DriverMock();
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.launchedTask);
+        assertEquals(1, mock.launchedTask.size());
+
+        Protos.TaskInfo taskInfo = mock.launchedTask.iterator().next();
+
+        assertEquals(4.0, resources(taskInfo.getResourcesList(), IgniteScheduler.CPU));
+        assertEquals(1024.0, resources(taskInfo.getResourcesList(), IgniteScheduler.MEM));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeclineByCpu() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 4, 1024);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.cpus(2);
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.launchedTask);
+        assertEquals(1, mock.launchedTask.size());
+
+        Protos.TaskInfo taskInfo = mock.launchedTask.iterator().next();
+
+        assertEquals(2.0, resources(taskInfo.getResourcesList(), IgniteScheduler.CPU));
+        assertEquals(1024.0, resources(taskInfo.getResourcesList(), IgniteScheduler.MEM));
+
+        mock.clear();
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNull(mock.launchedTask);
+
+        Protos.OfferID declinedOffer = mock.declinedOffer;
+
+        assertEquals(offer.getId(), declinedOffer);
+    }
+
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeclineByMem() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 4, 1024);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.memory(512);
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.launchedTask);
+        assertEquals(1, mock.launchedTask.size());
+
+        Protos.TaskInfo taskInfo = mock.launchedTask.iterator().next();
+
+        assertEquals(4.0, resources(taskInfo.getResourcesList(), IgniteScheduler.CPU));
+        assertEquals(512.0, resources(taskInfo.getResourcesList(), IgniteScheduler.MEM));
+
+        mock.clear();
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNull(mock.launchedTask);
+
+        Protos.OfferID declinedOffer = mock.declinedOffer;
+
+        assertEquals(offer.getId(), declinedOffer);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeclineByMemCpu() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 1, 1024);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.cpus(4);
+        clustProp.memory(2000);
+
+        scheduler.setClusterProps(clustProp);
+
+        double totalMem = 0, totalCpu = 0;
+
+        for (int i = 0; i < 2; i++) {
+            scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+            assertNotNull(mock.launchedTask);
+            assertEquals(1, mock.launchedTask.size());
+
+            Protos.TaskInfo taskInfo = mock.launchedTask.iterator().next();
+
+            totalCpu += resources(taskInfo.getResourcesList(), IgniteScheduler.CPU);
+            totalMem += resources(taskInfo.getResourcesList(), IgniteScheduler.MEM);
+
+            mock.clear();
+        }
+
+        assertEquals(2.0, totalCpu);
+        assertEquals(2000.0, totalMem);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNull(mock.launchedTask);
+
+        Protos.OfferID declinedOffer = mock.declinedOffer;
+
+        assertEquals(offer.getId(), declinedOffer);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeclineByCpuMinRequirements() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 8, 10240);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.minCpuPerNode(12);
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.declinedOffer);
+
+        assertEquals(offer.getId(), mock.declinedOffer);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDeclineByMemMinRequirements() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 8, 10240);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.minMemoryPerNode(15000);
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.declinedOffer);
+
+        assertEquals(offer.getId(), mock.declinedOffer);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testHosthameConstraint() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 8, 10240);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.hostnameConstraint(Pattern.compile("hostname"));
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.declinedOffer);
+
+        assertEquals(offer.getId(), mock.declinedOffer);
+
+        offer = createOffer("hostnameAccept", 8, 10240);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.launchedTask);
+        assertEquals(1, mock.launchedTask.size());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPerNode() throws Exception {
+        Protos.Offer offer = createOffer("hostname", 8, 1024);
+
+        DriverMock mock = new DriverMock();
+
+        ClusterProperties clustProp = new ClusterProperties();
+        clustProp.memoryPerNode(1024);
+        clustProp.cpusPerNode(2);
+
+        scheduler.setClusterProps(clustProp);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNotNull(mock.launchedTask);
+
+        Protos.TaskInfo taskInfo = mock.launchedTask.iterator().next();
+
+        assertEquals(2.0, resources(taskInfo.getResourcesList(), IgniteScheduler.CPU));
+        assertEquals(1024.0, resources(taskInfo.getResourcesList(), IgniteScheduler.MEM));
+
+        mock.clear();
+
+        offer = createOffer("hostname", 1, 2048);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNull(mock.launchedTask);
+
+        assertNotNull(mock.declinedOffer);
+        assertEquals(offer.getId(), mock.declinedOffer);
+
+        mock.clear();
+
+        offer = createOffer("hostname", 4, 512);
+
+        scheduler.resourceOffers(mock, Collections.singletonList(offer));
+
+        assertNull(mock.launchedTask);
+
+        assertNotNull(mock.declinedOffer);
+        assertEquals(offer.getId(), mock.declinedOffer);
+    }
+
+    /**
+     * @param resourceType Resource type.
+     * @return Value.
+     */
+    private Double resources(List<Protos.Resource> resources, String resourceType) {
+        for (Protos.Resource resource : resources) {
+            if (resource.getName().equals(resourceType))
+                return resource.getScalar().getValue();
+        }
+
+        return null;
+    }
+
+    /**
+     * @param hostname Hostname
+     * @param cpu Cpu count.
+     * @param mem Mem size.
+     * @return Offer.
+     */
+    private Protos.Offer createOffer(String hostname, double cpu, double mem) {
+        return Protos.Offer.newBuilder()
+            .setId(Protos.OfferID.newBuilder().setValue("1"))
+            .setSlaveId(Protos.SlaveID.newBuilder().setValue("1"))
+            .setFrameworkId(Protos.FrameworkID.newBuilder().setValue("1"))
+            .setHostname(hostname)
+            .addResources(Protos.Resource.newBuilder()
+                .setType(Protos.Value.Type.SCALAR)
+                .setName(IgniteScheduler.CPU)
+                .setScalar(Protos.Value.Scalar.newBuilder().setValue(cpu).build())
+                .build())
+            .addResources(Protos.Resource.newBuilder()
+                .setType(Protos.Value.Type.SCALAR)
+                .setName(IgniteScheduler.MEM)
+                .setScalar(Protos.Value.Scalar.newBuilder().setValue(mem).build())
+                .build())
+            .build();
+    }
+
+    /**
+     * No-op implementation.
+     */
+    public static class DriverMock implements SchedulerDriver {
+        /** */
+        Collection<Protos.TaskInfo> launchedTask;
+
+        /** */
+        Protos.OfferID declinedOffer;
+
+        /**
+         * Clears launched task.
+         */
+        public void clear() {
+            launchedTask = null;
+            declinedOffer = null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status start() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status stop(boolean failover) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status stop() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status abort() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status join() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status run() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status requestResources(Collection<Protos.Request> requests) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status launchTasks(Collection<Protos.OfferID> offerIds,
+            Collection<Protos.TaskInfo> tasks, Protos.Filters filters) {
+            launchedTask = tasks;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status launchTasks(Collection<Protos.OfferID> offerIds,
+            Collection<Protos.TaskInfo> tasks) {
+            launchedTask = tasks;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status launchTasks(Protos.OfferID offerId, Collection<Protos.TaskInfo> tasks,
+            Protos.Filters filters) {
+            launchedTask = tasks;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status launchTasks(Protos.OfferID offerId, Collection<Protos.TaskInfo> tasks) {
+            launchedTask = tasks;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status killTask(Protos.TaskID taskId) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status declineOffer(Protos.OfferID offerId, Protos.Filters filters) {
+            declinedOffer = offerId;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status declineOffer(Protos.OfferID offerId) {
+            declinedOffer = offerId;
+
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status reviveOffers() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status acknowledgeStatusUpdate(Protos.TaskStatus status) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status sendFrameworkMessage(Protos.ExecutorID executorId, Protos.SlaveID slaveId,
+            byte[] data) {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Protos.Status reconcileTasks(Collection<Protos.TaskStatus> statuses) {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/rest-http/pom.xml
----------------------------------------------------------------------
diff --git a/modules/rest-http/pom.xml b/modules/rest-http/pom.xml
index 9097614..64db144 100644
--- a/modules/rest-http/pom.xml
+++ b/modules/rest-http/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-rest-http</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/pom.xml
----------------------------------------------------------------------
diff --git a/modules/scalar/pom.xml b/modules/scalar/pom.xml
index 590d3f7..d3fcf2e 100644
--- a/modules/scalar/pom.xml
+++ b/modules/scalar/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-scalar</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/main/scala/org/apache/ignite/scalar/ScalarConversions.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/main/scala/org/apache/ignite/scalar/ScalarConversions.scala b/modules/scalar/src/main/scala/org/apache/ignite/scalar/ScalarConversions.scala
index d9565af..32e6758 100644
--- a/modules/scalar/src/main/scala/org/apache/ignite/scalar/ScalarConversions.scala
+++ b/modules/scalar/src/main/scala/org/apache/ignite/scalar/ScalarConversions.scala
@@ -867,14 +867,6 @@ trait ScalarConversions {
         GridFunc.as(r)
 
     /**
-     * Implicit converter from `java.util.concurrent.Callable` to `GridOutClosure`.
-     *
-     * @param c Java callable to convert.
-     */
-    implicit def toOutClosure2[R](c: java.util.concurrent.Callable[R]): IgniteOutClosure[R] =
-        GridFunc.as0(c)
-
-    /**
      * Implicit converter from Scala predicate to Scala wrapping predicate.
      *
      * @param f Scala predicate to convert.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheQueriesSpec.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheQueriesSpec.scala b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheQueriesSpec.scala
index 8d91fdc..2a11e5e 100644
--- a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheQueriesSpec.scala
+++ b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheQueriesSpec.scala
@@ -31,7 +31,7 @@ import scala.collection.JavaConversions._
  * Tests for Scalar cache queries API.
  */
 @RunWith(classOf[JUnitRunner])
-class ScalarCacheQueriesSpec extends FlatSpec with ShouldMatchers with BeforeAndAfterAll {
+class ScalarCacheQueriesSpec extends FunSpec with ShouldMatchers with BeforeAndAfterAll {
     /** Entries count. */
     private val ENTRY_CNT = 10
 
@@ -67,142 +67,142 @@ class ScalarCacheQueriesSpec extends FlatSpec with ShouldMatchers with BeforeAnd
         stop()
     }
 
-    behavior of "Scalar cache queries API"
+    describe("Scalar cache queries API") {
+        it("should correctly execute SCAN queries") {
+            var res = c.scan(classOf[ObjectValue], (k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
 
-    it should "correctly execute SCAN queries" in {
-        var res = c.scan(classOf[ObjectValue], (k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
+            assert(res.size == 2)
 
-        assert(res.size == 2)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
+            res = c.scan((k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
 
-        res = c.scan((k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
+            assert(res.size == 2)
 
-        assert(res.size == 2)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
+            res = c.scan(classOf[ObjectValue], (k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
 
-        res = c.scan(classOf[ObjectValue], (k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
+            assert(res.size == 2)
 
-        assert(res.size == 2)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
+            res = c.scan((k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
 
-        res = c.scan((k: Int, v: ObjectValue) => k > 5 && v.intVal < 8).getAll
+            assert(res.size == 2)
 
-        assert(res.size == 2)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
+        }
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey < 8 && t.getKey == t.getValue.intVal))
-    }
+        it("should correctly execute SQL queries") {
+            var res = c.sql(classOf[ObjectValue], "intVal > 5").getAll
 
-    it should "correctly execute SQL queries" in {
-        var res = c.sql(classOf[ObjectValue], "intVal > 5").getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql(classOf[ObjectValue], "intVal > ?", 5).getAll
 
-        res = c.sql(classOf[ObjectValue], "intVal > ?", 5).getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql("intVal > 5").getAll
 
-        res = c.sql("intVal > 5").getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql("intVal > ?", 5).getAll
 
-        res = c.sql("intVal > ?", 5).getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql(classOf[ObjectValue], "intVal > 5").getAll
 
-        res = c.sql(classOf[ObjectValue], "intVal > 5").getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql(classOf[ObjectValue], "intVal > ?", 5).getAll
 
-        res = c.sql(classOf[ObjectValue], "intVal > ?", 5).getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql("intVal > 5").getAll
 
-        res = c.sql("intVal > 5").getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+            res = c.sql("intVal > ?", 5).getAll
 
-        res = c.sql("intVal > ?", 5).getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
+        }
 
-        res.foreach(t => assert(t.getKey > 5 && t.getKey == t.getValue.intVal))
-    }
+        it("should correctly execute TEXT queries") {
+            var res = c.text(classOf[ObjectValue], "str").getAll
 
-    it should "correctly execute TEXT queries" in {
-        var res = c.text(classOf[ObjectValue], "str").getAll
+            assert(res.size == ENTRY_CNT)
 
-        assert(res.size == ENTRY_CNT)
+            res = c.text(classOf[ObjectValue], "five").getAll
 
-        res = c.text(classOf[ObjectValue], "five").getAll
+            assert(res.size == 1)
+            assert(res.head.getKey == 5)
 
-        assert(res.size == 1)
-        assert(res.head.getKey == 5)
+            res = c.text("str").getAll
 
-        res = c.text("str").getAll
+            assert(res.size == ENTRY_CNT)
 
-        assert(res.size == ENTRY_CNT)
+            res = c.text("five").getAll
 
-        res = c.text("five").getAll
+            assert(res.size == 1)
+            assert(res.head.getKey == 5)
 
-        assert(res.size == 1)
-        assert(res.head.getKey == 5)
+            res = c.text(classOf[ObjectValue], "str").getAll
 
-        res = c.text(classOf[ObjectValue], "str").getAll
+            assert(res.size == ENTRY_CNT)
 
-        assert(res.size == ENTRY_CNT)
+            res = c.text(classOf[ObjectValue], "five").getAll
 
-        res = c.text(classOf[ObjectValue], "five").getAll
+            assert(res.size == 1)
+            assert(res.head.getKey == 5)
 
-        assert(res.size == 1)
-        assert(res.head.getKey == 5)
+            res = c.text("str").getAll
 
-        res = c.text("str").getAll
+            assert(res.size == ENTRY_CNT)
 
-        assert(res.size == ENTRY_CNT)
+            res = c.text("five").getAll
 
-        res = c.text("five").getAll
+            assert(res.size == 1)
+            assert(res.head.getKey == 5)
+        }
 
-        assert(res.size == 1)
-        assert(res.head.getKey == 5)
-    }
+        it("should correctly execute fields queries") {
+            var res = c.sqlFields("select intVal from ObjectValue where intVal > 5").getAll
 
-    it should "correctly execute fields queries" in {
-        var res = c.sqlFields("select intVal from ObjectValue where intVal > 5").getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
+            res.foreach(t => assert(t.size == 1 && t.head.asInstanceOf[Int] > 5))
 
-        res.foreach(t => assert(t.size == 1 && t.head.asInstanceOf[Int] > 5))
+            res = c.sqlFields("select intVal from ObjectValue where intVal > ?", 5).getAll
 
-        res = c.sqlFields("select intVal from ObjectValue where intVal > ?", 5).getAll
+            assert(res.size == ENTRY_CNT - 5)
 
-        assert(res.size == ENTRY_CNT - 5)
-
-        res.foreach(t => assert(t.size == 1 && t.head.asInstanceOf[Int] > 5))
-    }
+            res.foreach(t => assert(t.size == 1 && t.head.asInstanceOf[Int] > 5))
+        }
 
-    it should "correctly execute queries with multiple arguments" in {
-        val res = c.sql("from ObjectValue where intVal in (?, ?, ?)", 1, 2, 3).getAll
+        it("should correctly execute queries with multiple arguments") {
+            val res = c.sql("from ObjectValue where intVal in (?, ?, ?)", 1, 2, 3).getAll
 
-        assert(res.size == 3)
+            assert(res.size == 3)
+        }
     }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheSpec.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheSpec.scala b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheSpec.scala
index 0fde48f..853cc16 100644
--- a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheSpec.scala
+++ b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarCacheSpec.scala
@@ -22,32 +22,35 @@ import org.apache.ignite.events.EventType._
 import org.apache.ignite.lang.IgnitePredicate
 import org.apache.ignite.scalar.scalar
 import org.apache.ignite.scalar.scalar._
+
 import org.junit.runner.RunWith
 import org.scalatest._
 import org.scalatest.junit.JUnitRunner
+
 import scala.collection.JavaConversions._
 
 /**
  * Scalar cache test.
  */
 @RunWith(classOf[JUnitRunner])
-class ScalarCacheSpec extends FlatSpec with ShouldMatchers {
+class ScalarCacheSpec extends FunSpec with ShouldMatchers {
     private val CFG = "modules/scalar/src/test/resources/spring-cache.xml"
 
-    behavior of "Scalar cache"
+    describe("Scalar cache") {
 
-    it should "work properly via Java APIs" in {
-        scalar(CFG) {
-            registerListener()
+        it("should work properly via Java APIs") {
+            scalar(CFG) {
+                registerListener()
 
-            val c = cache$[Int, Int]("partitioned").get
+                val c = cache$[Int, Int]("partitioned").get
 
-            c.put(1, 1)
-            c.put(2, 2)
+                c.put(1, 1)
+                c.put(2, 2)
 
-            c.iterator() foreach println
+                c.iterator() foreach println
 
-            println("Size is: " + c.size())
+                println("Size is: " + c.size())
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarConversionsSpec.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarConversionsSpec.scala b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarConversionsSpec.scala
index b20c755..c766422 100644
--- a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarConversionsSpec.scala
+++ b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarConversionsSpec.scala
@@ -21,7 +21,7 @@ import org.apache.ignite.internal.util.lang._
 import org.apache.ignite.lang._
 import org.apache.ignite.scalar.scalar._
 import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
+import org.scalatest._
 import org.scalatest.junit.JUnitRunner
 import org.scalatest.matchers.ShouldMatchers
 
@@ -31,10 +31,10 @@ import java.util.concurrent.atomic._
  *
  */
 @RunWith(classOf[JUnitRunner])
-class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
-    behavior of "Scalar mixin"
+class ScalarConversionsSpec extends FunSpec with ShouldMatchers {
+    describe("Scalar mixin") {
 
-    it should "convert reducer" in {
+    it("should convert reducer") {
         val r = new IgniteReducer[Int, Int] {
             var sum = 0
 
@@ -52,7 +52,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(r.scala.apply(Seq(1, 2, 3)) == 6)
     }
 
-    it should "convert reducer 2" in {
+    it("should convert reducer 2") {
         val r = new IgniteReducer2[Int, Int, Int] {
             var sum = 0
 
@@ -70,7 +70,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(r.scala.apply(Seq(1, 2), Seq(3, 4)) == 21)
     }
 
-    it should "convert reducer 3" in {
+    it("should convert reducer 3") {
         val r = new IgniteReducer3[Int, Int, Int, Int] {
             var sum = 0
 
@@ -88,14 +88,14 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(r.scala.apply(Seq(1, 2), Seq(1, 2), Seq(1, 2)) == 27)
     }
 
-    it should "convert tuple 2" in {
+    it("should convert tuple 2") {
         val t = new IgniteBiTuple[Int, Int](1, 2)
 
         assert(t.scala._1 == 1)
         assert(t.scala._2 == 2)
     }
 
-    it should "convert tuple 3" in {
+    it("should convert tuple 3") {
         val t = new GridTuple3[Int, Int, Int](1, 2, 3)
 
         assert(t.scala._1 == 1)
@@ -103,7 +103,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(t.scala._3 == 3)
     }
 
-    it should "convert tuple 4" in {
+    it("should convert tuple 4") {
         val t = new GridTuple4[Int, Int, Int, Int](1, 2, 3, 4)
 
         assert(t.scala._1 == 1)
@@ -112,7 +112,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(t.scala._4 == 4)
     }
 
-    it should "convert tuple 5" in {
+    it("should convert tuple 5") {
         val t = new GridTuple5[Int, Int, Int, Int, Int](1, 2, 3, 4, 5)
 
         assert(t.scala._1 == 1)
@@ -122,7 +122,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(t.scala._5 == 5)
     }
 
-    it should "convert in closure" in {
+    it("should convert in closure") {
         val i = new AtomicInteger()
 
         val f = new IgniteInClosure[Int] {
@@ -136,7 +136,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(i.get == 9)
     }
 
-    it should "convert in closure 2" in {
+    it("should convert in closure 2") {
         val i = new AtomicInteger()
 
         val f = new IgniteBiInClosure[Int, Int] {
@@ -150,7 +150,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(i.get == 6)
     }
 
-    it should "convert in closure 3" in {
+    it("should convert in closure 3") {
         val i = new AtomicInteger()
 
         val f = new GridInClosure3[Int, Int, Int] {
@@ -164,7 +164,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(i.get == 9)
     }
 
-    it should "convert absolute closure" in {
+    it("should convert absolute closure") {
         val i = new AtomicInteger()
 
         val f = new GridAbsClosure {
@@ -178,7 +178,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(i.get == 3)
     }
 
-    it should "convert absolute predicate" in {
+    it("should convert absolute predicate") {
         val i = new AtomicInteger()
 
         val p = new GridAbsPredicate {
@@ -195,7 +195,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(p.scala.apply())
     }
 
-    it should "convert predicate" in {
+    it("should convert predicate") {
         val p = new IgnitePredicate[Int] {
             override def apply(e: Int): Boolean =
                 e > 5
@@ -205,7 +205,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(p.scala.apply(6))
     }
 
-    it should "convert predicate 2" in {
+    it("should convert predicate 2") {
         val p = new IgniteBiPredicate[Int, Int] {
             override def apply(e1: Int, e2: Int): Boolean =
                 e1 + e2 > 5
@@ -215,7 +215,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(p.scala.apply(3, 3))
     }
 
-    it should "convert predicate 3" in {
+    it("should convert predicate 3") {
         val p = new GridPredicate3[Int, Int, Int] {
             override def apply(e1: Int, e2: Int, e3: Int): Boolean =
                 e1 + e2 + e3 > 5
@@ -225,7 +225,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(p.scala.apply(2, 2, 2))
     }
 
-    it should "convert closure" in {
+    it("should convert closure") {
         val f = new IgniteClosure[Int, Int] {
             override def apply(e: Int): Int =
                 e * 3
@@ -234,7 +234,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(f.scala.apply(3) == 9)
     }
 
-    it should "convert closure 2" in {
+    it("should convert closure 2") {
         val f = new IgniteBiClosure[Int, Int, Int] {
             override def apply(e1: Int, e2: Int): Int =
                 e1 + e2
@@ -243,7 +243,7 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
         assert(f.scala.apply(3, 3) == 6)
     }
 
-    it should "convert closure 3" in {
+    it("should convert closure 3") {
         val f = new GridClosure3[Int, Int, Int, Int] {
             override def apply(e1: Int, e2: Int, e3: Int): Int =
                 e1 + e2 + e3
@@ -251,4 +251,5 @@ class ScalarConversionsSpec extends FlatSpec with ShouldMatchers {
 
         assert(f.scala.apply(3, 3, 3) == 9)
     }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarProjectionSpec.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarProjectionSpec.scala b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarProjectionSpec.scala
index a035550..ecb1e5a 100644
--- a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarProjectionSpec.scala
+++ b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarProjectionSpec.scala
@@ -23,6 +23,7 @@ import org.apache.ignite.configuration.IgniteConfiguration
 import org.apache.ignite.messaging.MessagingListenActor
 import org.apache.ignite.scalar.scalar
 import org.apache.ignite.scalar.scalar._
+
 import org.junit.runner.RunWith
 import org.scalatest._
 import org.scalatest.junit.JUnitRunner
@@ -35,7 +36,7 @@ import scala.collection.JavaConversions._
  * Scalar cache test.
  */
 @RunWith(classOf[JUnitRunner])
-class ScalarProjectionSpec extends FlatSpec with ShouldMatchers with BeforeAndAfterAll {
+class ScalarProjectionSpec extends FunSpec with ShouldMatchers with BeforeAndAfterAll {
     /**
      *
      */
@@ -68,82 +69,95 @@ class ScalarProjectionSpec extends FlatSpec with ShouldMatchers with BeforeAndAf
         cfg
     }
 
-    behavior of "ScalarProjectionPimp class"
-
-    it should "return all nodes" in scalar(gridConfig("node-scalar", true)) {
-        assertResult(3) {
-            ignite$("node-scalar").get.cluster().nodes().size
+    describe("ScalarProjectionPimp class") {
+        it("should return all nodes") {
+            scalar(gridConfig("node-scalar", true)) {
+                assertResult(3)(ignite$("node-scalar").get.cluster().nodes().size)
+            }
         }
-    }
-
-    it should "return shown nodes" in  scalar(gridConfig("node-scalar", true)) {
-        assert(ignite$("node-scalar").get.nodes$((node: ClusterNode) => node.attribute[Boolean]("shown")).size == 2)
-    }
 
-    it should "return all remote nodes" in scalar(gridConfig("node-scalar", true)) {
-        assertResult(2) {
-            ignite$("node-scalar").get.remoteNodes$().size
+        it("should return shown nodes") {
+            scalar(gridConfig("node-scalar", true)) {
+                assert(ignite$("node-scalar").get.nodes$(
+                    (node: ClusterNode) => node.attribute[Boolean]("shown")).size == 2)
+            }
         }
-    }
-
-    it should "return shown remote nodes" in  scalar(gridConfig("node-scalar", true)) {
-        assert(ignite$("node-scalar").get.remoteNodes$((node: ClusterNode) =>
-            node.attribute[Boolean]("shown")).size == 1)
-    }
-
-    it should "correctly send messages" in scalar(gridConfig("node-scalar", true)) {
 
-        ignite$("node-1").get.message().remoteListen(null, new MessagingListenActor[Any]() {
-            def receive(nodeId: UUID, msg: Any) {
-                println("node-1 received " + msg)
+        it("should return all remote nodes") {
+            scalar(gridConfig("node-scalar", true)) {
+                assertResult(2)(ignite$("node-scalar").get.remoteNodes$().size)
             }
-        })
+        }
 
-        ignite$("node-2").get.message().remoteListen(null, new MessagingListenActor[Any]() {
-            def receive(nodeId: UUID, msg: Any) {
-                println("node-2 received " + msg)
+        it("should return shown remote nodes") {
+            scalar(gridConfig("node-scalar", true)) {
+                assert(ignite$("node-scalar").get.remoteNodes$((node: ClusterNode) =>
+                    node.attribute[Boolean]("shown")).size == 1)
             }
-        })
+        }
 
-        ignite$("node-scalar").get !< ("Message", null)
-        ignite$("node-scalar").get !< (Seq("Message1", "Message2"), null)
-    }
+        it("should correctly send messages") {
+            scalar(gridConfig("node-scalar", true)) {
+                ignite$("node-1").get.message().remoteListen(null, new MessagingListenActor[Any]() {
+                    def receive(nodeId: UUID, msg: Any) {
+                        println("node-1 received " + msg)
+                    }
+                })
+
+                ignite$("node-2").get.message().remoteListen(null, new MessagingListenActor[Any]() {
+                    def receive(nodeId: UUID, msg: Any) {
+                        println("node-2 received " + msg)
+                    }
+                })
+
+                ignite$("node-scalar").get !<("Message", null)
+                ignite$("node-scalar").get !<(Seq("Message1", "Message2"), null)
+            }
+        }
 
-    it should "correctly make calls" in scalar(gridConfig("node-scalar", true)) {
-        println("CALL RESULT: " + ignite$("node-scalar").get #< (() => "Message", null))
+        it("should correctly make calls") {
+            scalar(gridConfig("node-scalar", true)) {
+                println("CALL RESULT: " + ignite$("node-scalar").get #<(() => "Message", null))
 
-        println("ASYNC CALL RESULT: " + ignite$("node-scalar").get.callAsync$[String](() => "Message", null).get)
+                println("ASYNC CALL RESULT: " + ignite$("node-scalar").get.callAsync$[String](() => "Message", null).get)
 
-        val call1: () => String = () => "Message1"
-        val call2: () => String = () => "Message2"
+                val call1: () => String = () => "Message1"
+                val call2: () => String = () => "Message2"
 
-        println("MULTIPLE CALL RESULT: " + ignite$("node-scalar").get #< (Seq(call1, call2), null))
+                println("MULTIPLE CALL RESULT: " + ignite$("node-scalar").get #<(Seq(call1, call2), null))
 
-        println("MULTIPLE ASYNC CALL RESULT: " +
-            (ignite$("node-scalar").get #? (Seq(call1, call2), null)).get)
-    }
+                println("MULTIPLE ASYNC CALL RESULT: " +
+                    (ignite$("node-scalar").get #?(Seq(call1, call2), null)).get)
+            }
+        }
 
-    it should "correctly make runs" in scalar(gridConfig("node-scalar", true)) {
-        ignite$("node-scalar").get *< (() => println("RUN RESULT: Message"), null)
+        it("should correctly make runs") {
+            scalar(gridConfig("node-scalar", true)) {
+                ignite$("node-scalar").get *<(() => println("RUN RESULT: Message"), null)
 
-        (ignite$("node-scalar").get *? (() => println("ASYNC RUN RESULT: Message"), null)).get
+                (ignite$("node-scalar").get *?(() => println("ASYNC RUN RESULT: Message"), null)).get
 
-        val run1: () => Unit = () => println("RUN 1 RESULT: Message1")
-        val run2: () => Unit = () => println("RUN 2 RESULT: Message2")
+                val run1: () => Unit = () => println("RUN 1 RESULT: Message1")
+                val run2: () => Unit = () => println("RUN 2 RESULT: Message2")
 
-        ignite$("node-scalar").get *< (Seq(run1, run2), null)
+                ignite$("node-scalar").get *<(Seq(run1, run2), null)
 
-        val runAsync1: () => Unit = () => println("ASYNC RUN 1 RESULT: Message1")
-        val runAsync2: () => Unit = () => println("ASYNC RUN 2 RESULT: Message2")
+                val runAsync1: () => Unit = () => println("ASYNC RUN 1 RESULT: Message1")
+                val runAsync2: () => Unit = () => println("ASYNC RUN 2 RESULT: Message2")
 
-        (ignite$("node-scalar").get *? (Seq(runAsync1, runAsync2), null)).get
-    }
+                (ignite$("node-scalar").get *?(Seq(runAsync1, runAsync2), null)).get
+            }
+        }
 
-    it should "correctly reduce" in scalar(gridConfig("node-scalar", true)) {
-        val call1: () => Int = () => 15
-        val call2: () => Int = () => 82
+        it("should correctly reduce") {
+            scalar(gridConfig("node-scalar", true)) {
+                val call1: () => Int = () => 15
+                val call2: () => Int = () => 82
 
-        assert(ignite$("node-scalar").get @< (Seq(call1, call2), (n: Seq[Int]) => n.sum, null) == 97)
-        assert(ignite$("node-scalar").get.reduceAsync$(Seq(call1, call2), (n: Seq[Int]) => n.sum, null).get == 97)
+                assert(ignite$("node-scalar").get @<(Seq(call1, call2), (n: Seq[Int]) => n.sum, null) == 97)
+                assert(ignite$("node-scalar").get.reduceAsync$(Seq(call1, call2), (
+                    n: Seq[Int]) => n.sum, null).get == 97)
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarReturnableSpec.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarReturnableSpec.scala b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarReturnableSpec.scala
index 21e8cef..2927dd7 100644
--- a/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarReturnableSpec.scala
+++ b/modules/scalar/src/test/scala/org/apache/ignite/scalar/tests/ScalarReturnableSpec.scala
@@ -18,6 +18,7 @@
 package org.apache.ignite.scalar.tests
 
 import org.apache.ignite.scalar.scalar._
+
 import org.junit.runner.RunWith
 import org.scalatest._
 import org.scalatest.junit.JUnitRunner
@@ -28,30 +29,32 @@ import scala.util.control.Breaks._
  *
  */
 @RunWith(classOf[JUnitRunner])
-class ScalarReturnableSpec extends FlatSpec with ShouldMatchers {
-    "Scalar '^^'" should "work" in {
-        var i = 0
+class ScalarReturnableSpec extends FunSpec with ShouldMatchers {
+    describe("Scalar '^^'") {
+        it("should work") {
+            var i = 0
+
+            breakable {
+                while (true) {
+                    if (i == 0)
+                        println("Only once!") ^^
+
+                    i += 1
+                }
+            }
 
-        breakable {
-            while (true) {
-                if (i == 0)
-                    println("Only once!") ^^
+            assert(i == 0)
+        }
 
-                i += 1
+        // Ignore exception below.
+        def test() = breakable {
+            while (true) {
+                println("Only once!") ^^
             }
         }
 
-        assert(i == 0)
-    }
-
-    "Scalar '^^'" should "also work" in {
-        test()
-    }
-
-    // Ignore exception below.
-    def test() = breakable {
-        while (true) {
-            println("Only once!") ^^
+        it("should also work") {
+            test()
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/schedule/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schedule/pom.xml b/modules/schedule/pom.xml
index 2c09ed9..cac133f 100644
--- a/modules/schedule/pom.xml
+++ b/modules/schedule/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-schedule</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/schema-import/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-import/pom.xml b/modules/schema-import/pom.xml
index 7c49cab..64f85d9 100644
--- a/modules/schema-import/pom.xml
+++ b/modules/schema-import/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-schema-import</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>
@@ -84,9 +84,11 @@
 
     <profiles>
         <profile>
-            <id>jfxrt.jar</id>
+            <id>schema-import</id>
             <activation>
-                <jdk>[1.7,1.8)</jdk>
+                <file>
+                    <exists>${java.home}/lib/jfxrt.jar</exists>
+                </file>
             </activation>
             <dependencies>
                 <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/schema-import/src/main/java/org/apache/ignite/schema/generator/CodeGenerator.java
----------------------------------------------------------------------
diff --git a/modules/schema-import/src/main/java/org/apache/ignite/schema/generator/CodeGenerator.java b/modules/schema-import/src/main/java/org/apache/ignite/schema/generator/CodeGenerator.java
index f8901d2..b92d84b 100644
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/generator/CodeGenerator.java
+++ b/modules/schema-import/src/main/java/org/apache/ignite/schema/generator/CodeGenerator.java
@@ -69,7 +69,7 @@ public class CodeGenerator {
      * @throws IllegalStateException If passed string is not valid java identifier.
      */
     private static void checkValidJavaIdentifier(String identifier, boolean split, String msg, String type)
-        throws IllegalStateException{
+        throws IllegalStateException {
         if (identifier.isEmpty())
             throw new IllegalStateException(msg + " could not be empty!");
 
@@ -550,21 +550,25 @@ public class CodeGenerator {
      * @param mtdName Method name to generate.
      * @param comment Commentary text.
      * @param first {@code true} if variable should be declared.
+     * @return {@code false} if variable was declared.
      */
-    private static void addQueryFields(Collection<String> src, Collection<PojoField> fields, String varName,
+    private static boolean addQueryFields(Collection<String> src, Collection<PojoField> fields, String varName,
         String mtdName, String comment, boolean first) {
-        if (!fields.isEmpty()) {
-            add2(src, comment);
-            add2(src, (first ? "Map<String, Class<?>> " : "") + varName + " = new LinkedHashMap<>();");
-            add0(src, "");
+        if (fields.isEmpty())
+            return true;
 
-            for (PojoField field : fields)
-                add2(src, varName + ".put(\"" + field.javaName() + "\", " + javaTypeName(field) + ".class);");
+        add2(src, comment);
+        add2(src, (first ? "Map<String, Class<?>> " : "") + varName + " = new LinkedHashMap<>();");
+        add0(src, "");
 
-            add0(src, "");
-            add2(src, "type." + mtdName + "(" + varName + ");");
-            add0(src, "");
-        }
+        for (PojoField field : fields)
+            add2(src, varName + ".put(\"" + field.javaName() + "\", " + javaTypeName(field) + ".class);");
+
+        add0(src, "");
+        add2(src, "type." + mtdName + "(" + varName + ");");
+        add0(src, "");
+
+        return false;
     }
 
     /**
@@ -623,6 +627,9 @@ public class CodeGenerator {
         add0(src, "");
 
         boolean first = true;
+        boolean firstAsc = true;
+        boolean firstDesc = true;
+        boolean firstGrps = true;
         boolean firstGrp = true;
 
         for (PojoDescriptor pojo : pojos) {
@@ -661,25 +668,27 @@ public class CodeGenerator {
             addQueryFields(src, pojo.fields(), "qryFlds", "setQueryFields", "// Query fields for " + tbl + ".", first);
 
             // Ascending fields.
-            addQueryFields(src, pojo.ascendingFields(), "ascFlds", "setAscendingFields",
-                "// Ascending fields for " + tbl + ".", first);
+            firstAsc = addQueryFields(src, pojo.ascendingFields(), "ascFlds", "setAscendingFields",
+                "// Ascending fields for " + tbl + ".", firstAsc);
 
             // Descending fields.
-            addQueryFields(src, pojo.descendingFields(), "descFlds", "setDescendingFields",
-                "// Descending fields for " + tbl + ".", first);
+            firstDesc = addQueryFields(src, pojo.descendingFields(), "descFlds", "setDescendingFields",
+                "// Descending fields for " + tbl + ".", firstDesc);
 
             // Groups.
             Map<String, Map<String, IndexItem>> groups = pojo.groups();
 
             if (!groups.isEmpty()) {
                 add2(src, "// Groups for " + tbl + ".");
-                add2(src, (first ? "Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> " : "") +
-                    " grps = new LinkedHashMap<>();");
+                add2(src, (firstGrps ? "Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> " : "") +
+                    "grps = new LinkedHashMap<>();");
                 add0(src, "");
 
+                firstGrps = false;
+
                 for (Map.Entry<String, Map<String, IndexItem>> group : groups.entrySet()) {
                     add2(src, (firstGrp ? "LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> " : "") +
-                            "grpItems = new LinkedHashMap<>();");
+                        "grpItems = new LinkedHashMap<>();");
                     add0(src, "");
 
                     for (Map.Entry<String, IndexItem> grpItem : group.getValue().entrySet()) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/slf4j/pom.xml
----------------------------------------------------------------------
diff --git a/modules/slf4j/pom.xml b/modules/slf4j/pom.xml
index 1f78f42..7c1e660 100644
--- a/modules/slf4j/pom.xml
+++ b/modules/slf4j/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-slf4j</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/spring/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spring/pom.xml b/modules/spring/pom.xml
index 1390a39..e922215 100644
--- a/modules/spring/pom.xml
+++ b/modules/spring/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-spring</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/spring/src/main/java/org/apache/ignite/internal/util/spring/IgniteSpringHelperImpl.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/apache/ignite/internal/util/spring/IgniteSpringHelperImpl.java b/modules/spring/src/main/java/org/apache/ignite/internal/util/spring/IgniteSpringHelperImpl.java
index f05e991..2c7c7e1 100644
--- a/modules/spring/src/main/java/org/apache/ignite/internal/util/spring/IgniteSpringHelperImpl.java
+++ b/modules/spring/src/main/java/org/apache/ignite/internal/util/spring/IgniteSpringHelperImpl.java
@@ -399,7 +399,7 @@ public class IgniteSpringHelperImpl implements IgniteSpringHelper {
      * Prepares Spring context.
      *
      * @param excludedProps Properties to be excluded.
-     * @return
+     * @return application context.
      */
     private static GenericApplicationContext prepareSpringContext(final String... excludedProps){
         GenericApplicationContext springCtx = new GenericApplicationContext();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/ssh/pom.xml
----------------------------------------------------------------------
diff --git a/modules/ssh/pom.xml b/modules/ssh/pom.xml
index 867e9be..0dcbd80 100644
--- a/modules/ssh/pom.xml
+++ b/modules/ssh/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-ssh</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/ssh/src/test/java/org/apache/ignite/internal/IgniteProjectionStartStopRestartSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/ssh/src/test/java/org/apache/ignite/internal/IgniteProjectionStartStopRestartSelfTest.java b/modules/ssh/src/test/java/org/apache/ignite/internal/IgniteProjectionStartStopRestartSelfTest.java
index 7fa5b4b..3618c2c 100644
--- a/modules/ssh/src/test/java/org/apache/ignite/internal/IgniteProjectionStartStopRestartSelfTest.java
+++ b/modules/ssh/src/test/java/org/apache/ignite/internal/IgniteProjectionStartStopRestartSelfTest.java
@@ -131,7 +131,8 @@ public class IgniteProjectionStartStopRestartSelfTest extends GridCommonAbstract
 
                     if (joinedLatch != null)
                         joinedLatch.countDown();
-                } else if (evt.type() == EVT_NODE_LEFT) {
+                }
+                else if (evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED) {
                     leftCnt.incrementAndGet();
 
                     if (leftLatch != null)
@@ -140,20 +141,26 @@ public class IgniteProjectionStartStopRestartSelfTest extends GridCommonAbstract
 
                 return true;
             }
-        }, EVT_NODE_JOINED, EVT_NODE_LEFT);
+        }, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED);
     }
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
-        if (!ignite.cluster().nodes().isEmpty()) {
-            leftLatch = new CountDownLatch(ignite.cluster().nodes().size());
+        boolean wasEmpty = true;
 
-            ignite.cluster().stopNodes();
+        if (ignite != null) {
+            if (!ignite.cluster().nodes().isEmpty()) {
+                leftLatch = new CountDownLatch(ignite.cluster().nodes().size());
 
-            assert leftLatch.await(WAIT_TIMEOUT, MILLISECONDS);
-        }
+                ignite.cluster().stopNodes();
 
-        boolean wasEmpty = ignite.cluster().nodes().isEmpty();
+                assert leftLatch.await(
+                    WAIT_TIMEOUT,
+                    MILLISECONDS);
+            }
+
+            wasEmpty = ignite.cluster().nodes().isEmpty();
+        }
 
         G.stop(true);
 
@@ -163,7 +170,8 @@ public class IgniteProjectionStartStopRestartSelfTest extends GridCommonAbstract
         joinedLatch = null;
         leftLatch = null;
 
-        assert wasEmpty : "grid.isEmpty() returned false after all nodes were stopped [nodes=" + ignite.cluster().nodes() + ']';
+        assert wasEmpty : "grid.isEmpty() returned false after all nodes were stopped " +
+            "[nodes=" + ignite.cluster().nodes() + ']';
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/tools/pom.xml
----------------------------------------------------------------------
diff --git a/modules/tools/pom.xml b/modules/tools/pom.xml
index 625eeaa..2351d95 100644
--- a/modules/tools/pom.xml
+++ b/modules/tools/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-tools</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96f0956d/modules/urideploy/pom.xml
----------------------------------------------------------------------
diff --git a/modules/urideploy/pom.xml b/modules/urideploy/pom.xml
index 231a576..c6abfe5 100644
--- a/modules/urideploy/pom.xml
+++ b/modules/urideploy/pom.xml
@@ -31,7 +31,7 @@
     </parent>
 
     <artifactId>ignite-urideploy</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
 
     <dependencies>
         <dependency>