diff --git a/app/code/Magento/Authorization/Setup/InstallSchema.php b/app/code/Magento/Authorization/Setup/InstallSchema.php
index d2199ef50ff836939de4a8b930482e744222390c..be78cce218735960373e7c04510390fe56f06186 100644
--- a/app/code/Magento/Authorization/Setup/InstallSchema.php
+++ b/app/code/Magento/Authorization/Setup/InstallSchema.php
@@ -138,7 +138,6 @@ class InstallSchema implements InstallSchemaInterface
                 'role_id',
                 $installer->getTable('authorization_role'),
                 'role_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )->setComment(
                 'Admin Rule Table'
diff --git a/app/code/Magento/Bundle/Setup/InstallSchema.php b/app/code/Magento/Bundle/Setup/InstallSchema.php
index 96f43cb95704dbcf8d9e672be049493bfccab912..94325c54ff13c965a23e20a7b1962818b5816d2f 100644
--- a/app/code/Magento/Bundle/Setup/InstallSchema.php
+++ b/app/code/Magento/Bundle/Setup/InstallSchema.php
@@ -79,7 +79,6 @@ class InstallSchema implements InstallSchemaInterface
                 'parent_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Bundle Option');
@@ -138,7 +137,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('catalog_product_bundle_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Bundle Option Value');
@@ -238,7 +236,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('catalog_product_bundle_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -251,7 +248,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Bundle Selection');
@@ -305,7 +301,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -318,7 +313,6 @@ class InstallSchema implements InstallSchemaInterface
                 'selection_id',
                 $installer->getTable('catalog_product_bundle_selection'),
                 'selection_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Bundle Selection Price');
@@ -383,7 +377,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -396,7 +389,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -409,7 +401,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Bundle Price Index');
diff --git a/app/code/Magento/CacheInvalidate/Model/Observer.php b/app/code/Magento/CacheInvalidate/Model/Observer.php
new file mode 100644
index 0000000000000000000000000000000000000000..6deb4f50aac511b57fc7bf5cf920a6f172bad351
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/Model/Observer.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CacheInvalidate\Model;
+
+/**
+ * Class Observer
+ */
+class Observer
+{
+    /**
+     * Application config object
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $_config;
+
+    /**
+     * @var \Magento\PageCache\Helper\Data
+     */
+    protected $_helper;
+
+    /**
+     * @var \Magento\Framework\HTTP\Adapter\Curl
+     */
+    protected $_curlAdapter;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\PageCache\Model\Config $config
+     * @param \Magento\PageCache\Helper\Data $helper
+     * @param \Magento\Framework\HTTP\Adapter\Curl $curlAdapter
+     */
+    public function __construct(
+        \Magento\PageCache\Model\Config $config,
+        \Magento\PageCache\Helper\Data $helper,
+        \Magento\Framework\HTTP\Adapter\Curl $curlAdapter
+    ) {
+        $this->_config = $config;
+        $this->_helper = $helper;
+        $this->_curlAdapter = $curlAdapter;
+    }
+
+    /**
+     * If Varnish caching is enabled it collects array of tags
+     * of incoming object and asks to clean cache.
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return void
+     */
+    public function invalidateVarnish(\Magento\Framework\Event\Observer $observer)
+    {
+        if ($this->_config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->_config->isEnabled()) {
+            $object = $observer->getEvent()->getObject();
+            if ($object instanceof \Magento\Framework\Object\IdentityInterface) {
+                $tags = [];
+                $pattern = "((^|,)%s(,|$))";
+                foreach ($object->getIdentities() as $tag) {
+                    $tags[] = sprintf($pattern, preg_replace("~_\\d+$~", '', $tag));
+                    $tags[] = sprintf($pattern, $tag);
+                }
+                $this->sendPurgeRequest(implode('|', array_unique($tags)));
+            }
+        }
+    }
+
+    /**
+     * Flash Varnish cache
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function flushAllCache(\Magento\Framework\Event\Observer $observer)
+    {
+        if ($this->_config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->_config->isEnabled()) {
+            $this->sendPurgeRequest('.*');
+        }
+    }
+
+    /**
+     * Send curl purge request
+     * to invalidate cache by tags pattern
+     *
+     * @param string $tagsPattern
+     * @return void
+     */
+    protected function sendPurgeRequest($tagsPattern)
+    {
+        $headers = ["X-Magento-Tags-Pattern: {$tagsPattern}"];
+        $this->_curlAdapter->setOptions([CURLOPT_CUSTOMREQUEST => 'PURGE']);
+        $this->_curlAdapter->write('', $this->_helper->getUrl('*'), '1.1', $headers);
+        $this->_curlAdapter->read();
+        $this->_curlAdapter->close();
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/README.md b/app/code/Magento/CacheInvalidate/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6cca6ffec03e45b5b7c09ba7d6e8a6543e14eb00
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/README.md
@@ -0,0 +1,2 @@
+The CacheInvalidate module is used to invalidate the Varnish cache if it is configured.
+It listens for events that request the cache to be flushed or cause the cache to be invalid, then sends Varnish a purge request using cURL.
\ No newline at end of file
diff --git a/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php b/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1abf5d45605acb48f111f7126ab58dcae9c9e540
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/Test/Unit/Model/ObserverTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CacheInvalidate\Test\Unit\Model;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\CacheInvalidate\Model\Observer */
+    protected $_model;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Event\Observer */
+    protected $_observerMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\HTTP\Adapter\Curl */
+    protected $_curlMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\PageCache\Model\Config */
+    protected $_configMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\PageCache\Helper\Data */
+    protected $_helperMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Object\ */
+    protected $_observerObject;
+
+    /**
+     * Set up all mocks and data for test
+     */
+    public function setUp()
+    {
+        $this->_configMock = $this->getMock(
+            'Magento\PageCache\Model\Config',
+            ['getType', 'isEnabled'],
+            [],
+            '',
+            false
+        );
+        $this->_helperMock = $this->getMock('Magento\PageCache\Helper\Data', ['getUrl'], [], '', false);
+        $this->_curlMock = $this->getMock(
+            '\Magento\Framework\HTTP\Adapter\Curl',
+            ['setOptions', 'write', 'read', 'close'],
+            [],
+            '',
+            false
+        );
+        $this->_model = new \Magento\CacheInvalidate\Model\Observer(
+            $this->_configMock,
+            $this->_helperMock,
+            $this->_curlMock
+        );
+        $this->_observerMock = $this->getMock(
+            'Magento\Framework\Event\Observer',
+            ['getEvent'],
+            [],
+            '',
+            false
+        );
+        $this->_observerObject = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+    }
+
+    /**
+     * Test case for cache invalidation
+     */
+    public function testInvalidateVarnish()
+    {
+        $tags = ['cache_1', 'cache_group'];
+        $pattern = '((^|,)cache(,|$))|((^|,)cache_1(,|$))|((^|,)cache_group(,|$))';
+
+        $this->_configMock->expects($this->once())->method('isEnabled')->will($this->returnValue(true));
+        $this->_configMock->expects(
+            $this->once()
+        )->method(
+            'getType'
+        )->will(
+            $this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
+        );
+        $eventMock = $this->getMock('Magento\Framework\Event', ['getObject'], [], '', false);
+        $eventMock->expects($this->once())->method('getObject')->will($this->returnValue($this->_observerObject));
+        $this->_observerMock->expects($this->once())->method('getEvent')->will($this->returnValue($eventMock));
+        $this->_observerObject->expects($this->once())->method('getIdentities')->will($this->returnValue($tags));
+        $this->sendPurgeRequest($pattern);
+
+        $this->_model->invalidateVarnish($this->_observerMock);
+    }
+
+    /**
+     * Test case for flushing all the cache
+     */
+    public function testFlushAllCache()
+    {
+        $this->_configMock->expects($this->once())->method('isEnabled')->will($this->returnValue(true));
+        $this->_configMock->expects(
+            $this->once()
+        )->method(
+            'getType'
+        )->will(
+            $this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
+        );
+
+        $this->sendPurgeRequest('.*');
+        $this->_model->flushAllCache($this->_observerMock);
+    }
+
+    /**
+     * @param string $tags
+     */
+    protected function sendPurgeRequest($tags)
+    {
+        $url = 'http://mangento.index.php';
+        $httpVersion = '1.1';
+        $headers = ["X-Magento-Tags-Pattern: {$tags}"];
+        $this->_helperMock->expects(
+            $this->any()
+        )->method(
+            'getUrl'
+        )->with(
+            $this->equalTo('*'),
+            []
+        )->will(
+            $this->returnValue($url)
+        );
+        $this->_curlMock->expects($this->once())->method('setOptions')->with([CURLOPT_CUSTOMREQUEST => 'PURGE']);
+        $this->_curlMock->expects(
+            $this->once()
+        )->method(
+            'write'
+        )->with(
+            $this->equalTo(''),
+            $this->equalTo($url),
+            $httpVersion,
+            $this->equalTo($headers)
+        );
+        $this->_curlMock->expects($this->once())->method('read');
+        $this->_curlMock->expects($this->once())->method('close');
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..3fe142a52e825fe6bae3ab6d56e798302d3ba3c3
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/composer.json
@@ -0,0 +1,24 @@
+{
+    "name": "magento/module-cache-invalidate",
+    "description": "N/A",
+    "require": {
+        "php": "~5.5.0|~5.6.0",
+        "magento/module-page-cache": "0.74.0-beta4",
+        "magento/framework": "0.74.0-beta4",
+        "magento/magento-composer-installer": "*"
+    },
+    "type": "magento2-module",
+    "version": "0.74.0-beta4",
+    "license": [
+        "OSL-3.0",
+        "AFL-3.0"
+    ],
+    "extra": {
+        "map": [
+            [
+                "*",
+                "Magento/CacheInvalidate"
+            ]
+        ]
+    }
+}
diff --git a/app/code/Magento/CacheInvalidate/etc/events.xml b/app/code/Magento/CacheInvalidate/etc/events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4ba3665ee66fb4e1e1eee75045302c199bf2985
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/etc/events.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="clean_cache_by_tags">
+        <observer name="invalidate_varnish" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="adminhtml_cache_flush_system">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="clean_media_cache_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="clean_catalog_images_cache_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="assigned_theme_changed">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="catalogrule_after_apply">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="adminhtml_cache_refresh_type">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="adminhtml_cache_flush_all">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="assign_theme_to_stores_after">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="flushAllCache" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_currency_saveRates">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_config_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_catalog_product_action_attribute_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_catalog_product_massStatus">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+    <event name="controller_action_postdispatch_adminhtml_system_currencysymbol_save">
+        <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Model\Observer" method="invalidateVarnish" />
+    </event>
+</config>
diff --git a/app/code/Magento/CacheInvalidate/etc/module.xml b/app/code/Magento/CacheInvalidate/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ca87df877a43a93eb2be450fa10b0013d099eff9
--- /dev/null
+++ b/app/code/Magento/CacheInvalidate/etc/module.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_CacheInvalidate" setup_version="2.0.0">
+        <sequence>
+            <module name="Magento_Store"/>
+        </sequence>
+    </module>
+</config>
diff --git a/app/code/Magento/Catalog/Setup/InstallSchema.php b/app/code/Magento/Catalog/Setup/InstallSchema.php
index 1ca2468ed2a4ef213c22bfb9b7a31c0aaa6e322c..d2dc790edb124beb7e7aaa34c86114e7a17ff7e2 100644
--- a/app/code/Magento/Catalog/Setup/InstallSchema.php
+++ b/app/code/Magento/Catalog/Setup/InstallSchema.php
@@ -115,7 +115,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_set_id',
                 $installer->getTable('eav_attribute_set'),
                 'attribute_set_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -123,7 +122,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_type_id',
                 $installer->getTable('eav_entity_type'),
                 'entity_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Table');
@@ -203,7 +201,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -216,7 +213,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -224,7 +220,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Datetime Attribute Backend Table');
@@ -304,7 +299,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -317,7 +311,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -325,7 +318,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Decimal Attribute Backend Table');
@@ -400,7 +392,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -408,7 +399,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -416,7 +406,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Integer Attribute Backend Table');
@@ -496,7 +485,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -509,7 +497,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -517,7 +504,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Text Attribute Backend Table');
@@ -597,7 +583,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -610,7 +595,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -618,7 +602,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Varchar Attribute Backend Table');
@@ -709,7 +692,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -722,7 +704,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -730,7 +711,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Gallery Attribute Backend Table');
@@ -896,7 +876,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -909,7 +888,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -917,7 +895,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Category Datetime Attribute Backend Table');
@@ -1001,7 +978,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1014,7 +990,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1022,7 +997,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Category Decimal Attribute Backend Table');
@@ -1101,7 +1075,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1114,7 +1087,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1122,7 +1094,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Category Integer Attribute Backend Table');
@@ -1201,7 +1172,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1214,7 +1184,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1222,7 +1191,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Category Text Attribute Backend Table');
@@ -1306,7 +1274,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1319,7 +1286,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1327,7 +1293,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Category Varchar Attribute Backend Table');
@@ -1373,7 +1338,6 @@ class InstallSchema implements InstallSchemaInterface
                 'category_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1381,7 +1345,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product To Category Linkage Table');
@@ -1514,7 +1477,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_id',
                 $installer->getTable('customer_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1522,7 +1484,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1530,8 +1491,7 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment(
                 'Catalog Compare Table'
@@ -1569,7 +1529,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1577,7 +1536,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -1675,7 +1633,6 @@ class InstallSchema implements InstallSchemaInterface
                 'linked_product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1683,7 +1640,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1696,7 +1652,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_type_id',
                 $installer->getTable('catalog_product_link_type'),
                 'link_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -1754,7 +1709,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_type_id',
                 $installer->getTable('catalog_product_link_type'),
                 'link_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -1821,7 +1775,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_id',
                 $installer->getTable('catalog_product_link'),
                 'link_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1834,7 +1787,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_link_attribute_id',
                 $installer->getTable('catalog_product_link_attribute'),
                 'product_link_attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -1901,7 +1853,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_id',
                 $installer->getTable('catalog_product_link'),
                 'link_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1914,7 +1865,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_link_attribute_id',
                 $installer->getTable('catalog_product_link_attribute'),
                 'product_link_attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -1981,7 +1931,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_id',
                 $installer->getTable('catalog_product_link'),
                 'link_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -1994,7 +1943,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_link_attribute_id',
                 $installer->getTable('catalog_product_link_attribute'),
                 'product_link_attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2086,7 +2034,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2099,7 +2046,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2107,7 +2053,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2169,7 +2114,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2182,7 +2126,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2258,7 +2201,6 @@ class InstallSchema implements InstallSchemaInterface
                 'value_id',
                 $installer->getTable('catalog_product_entity_media_gallery'),
                 'value_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2266,7 +2208,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2279,7 +2220,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2374,7 +2314,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2448,7 +2387,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('catalog_product_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2456,7 +2394,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2523,7 +2460,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('catalog_product_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2531,7 +2467,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2663,7 +2598,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_type_id',
                 $installer->getTable('catalog_product_option_type_value'),
                 'option_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2671,7 +2605,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2738,7 +2671,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_type_id',
                 $installer->getTable('catalog_product_option_type_value'),
                 'option_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2746,7 +2678,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2908,7 +2839,6 @@ class InstallSchema implements InstallSchemaInterface
                 'attribute_id',
                 $installer->getTable('eav_attribute'),
                 'attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -2947,7 +2877,6 @@ class InstallSchema implements InstallSchemaInterface
                 'child_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -2955,7 +2884,6 @@ class InstallSchema implements InstallSchemaInterface
                 'parent_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -3169,7 +3097,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -3182,7 +3109,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -3190,7 +3116,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -3252,7 +3177,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -3265,7 +3189,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -3273,7 +3196,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -3319,7 +3241,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -4605,7 +4526,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -4618,7 +4538,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -4631,7 +4550,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
@@ -4694,7 +4612,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -4707,7 +4624,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -4715,7 +4631,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment(
diff --git a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
index d7730876dd43e08eec57a8789f719d4262a2b3fa..aa6705a61ca829bc17506700a82eaaef67602093 100644
--- a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
+++ b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php
@@ -283,7 +283,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -291,7 +290,6 @@ class InstallSchema implements InstallSchemaInterface
                 'stock_id',
                 $installer->getTable('cataloginventory_stock'),
                 'stock_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Cataloginventory Stock Item');
diff --git a/app/code/Magento/CatalogRule/Setup/InstallSchema.php b/app/code/Magento/CatalogRule/Setup/InstallSchema.php
index 7c9fd560f92a857956d04366b247c52e8b33690e..610434b70a4448f545de5db717fc93e15dfced94 100644
--- a/app/code/Magento/CatalogRule/Setup/InstallSchema.php
+++ b/app/code/Magento/CatalogRule/Setup/InstallSchema.php
@@ -418,7 +418,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -426,7 +425,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rule_id',
                 $installer->getTable('catalogrule'),
                 'rule_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -434,7 +432,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('CatalogRule Group Website');
@@ -469,7 +466,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rule_id',
                 $installer->getTable('catalogrule'),
                 'rule_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -477,7 +473,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Rules To Websites Relations');
@@ -512,7 +507,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rule_id',
                 $installer->getTable('catalogrule'),
                 'rule_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -525,7 +519,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_group_id',
                 $installer->getTable('customer_group'),
                 'customer_group_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Rules To Customer Groups Relations');
diff --git a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
index baed812982fcbaf707c62d6b2c37c2851617f93e..88acf7808b614cd0654f92eecd70e37f27cc9200 100644
--- a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
+++ b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php
@@ -57,7 +57,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -65,7 +64,6 @@ class InstallSchema implements InstallSchemaInterface
                 'category_id',
                 $installer->getTable('catalog_category_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -73,7 +71,6 @@ class InstallSchema implements InstallSchemaInterface
                 'url_rewrite_id',
                 $installer->getTable('url_rewrite'),
                 'url_rewrite_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('url_rewrite_relation');
diff --git a/app/code/Magento/Checkout/Block/Cart/Shipping.php b/app/code/Magento/Checkout/Block/Cart/Shipping.php
index 27f72fb347f391cd41e74da27eb83713e46abd1a..8cf93dd33eaa66b2e65598029299152b508dc991 100644
--- a/app/code/Magento/Checkout/Block/Cart/Shipping.php
+++ b/app/code/Magento/Checkout/Block/Cart/Shipping.php
@@ -34,7 +34,7 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
     protected $_directoryBlock;
 
     /**
-     * @var \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface
+     * @var \Magento\Shipping\Model\CarrierFactoryInterface
      */
     protected $_carrierFactory;
 
@@ -48,7 +48,7 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Directory\Block\Data $directoryBlock
-     * @param \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface $carrierFactory
+     * @param \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory
      * @param PriceCurrencyInterface $priceCurrency
      * @param array $data
      */
@@ -57,7 +57,7 @@ class Shipping extends \Magento\Checkout\Block\Cart\AbstractCart
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Directory\Block\Data $directoryBlock,
-        \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface $carrierFactory,
+        \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory,
         PriceCurrencyInterface $priceCurrency,
         array $data = []
     ) {
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index 50db79346bdbb9c2e5c0f05a300135a83e6d7161..2877afcf85ed8820a084c34cd72c03874baf4996 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -10,6 +10,7 @@
         "magento/module-customer": "0.74.0-beta4",
         "magento/module-catalog": "0.74.0-beta4",
         "magento/module-payment": "0.74.0-beta4",
+        "magento/module-shipping": "0.74.0-beta4",
         "magento/module-tax": "0.74.0-beta4",
         "magento/module-directory": "0.74.0-beta4",
         "magento/module-eav": "0.74.0-beta4",
diff --git a/app/code/Magento/CheckoutAgreements/Setup/InstallSchema.php b/app/code/Magento/CheckoutAgreements/Setup/InstallSchema.php
index 2b782a0ed9bf781c7f262f24df3f87c3d9ada9bc..d4df1585bb67b80436fde0e266ddaef1225b6bd1 100644
--- a/app/code/Magento/CheckoutAgreements/Setup/InstallSchema.php
+++ b/app/code/Magento/CheckoutAgreements/Setup/InstallSchema.php
@@ -97,14 +97,12 @@ class InstallSchema implements InstallSchemaInterface
             'agreement_id',
             $installer->getTable('checkout_agreement'),
             'agreement_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('checkout_agreement_store', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Checkout Agreement Store'
diff --git a/app/code/Magento/Cms/Setup/InstallSchema.php b/app/code/Magento/Cms/Setup/InstallSchema.php
index d57b656b110393c18585834c08f84c813fad474e..00c2eba7289fe191a41b801fc3c8ad0749a4c20a 100644
--- a/app/code/Magento/Cms/Setup/InstallSchema.php
+++ b/app/code/Magento/Cms/Setup/InstallSchema.php
@@ -102,14 +102,12 @@ class InstallSchema implements InstallSchemaInterface
             'block_id',
             $installer->getTable('cms_block'),
             'block_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('cms_block_store', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'CMS Block To Store Linkage Table'
@@ -262,14 +260,12 @@ class InstallSchema implements InstallSchemaInterface
             'page_id',
             $installer->getTable('cms_page'),
             'page_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('cms_page_store', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'CMS Page To Store Linkage Table'
diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallSchema.php b/app/code/Magento/ConfigurableProduct/Setup/InstallSchema.php
index 51ce770c9aa042b6da48a047baa8752c3e67f706..d4514e8618dbdb4f9f62f98d9ea828d10d7ad6be 100644
--- a/app/code/Magento/ConfigurableProduct/Setup/InstallSchema.php
+++ b/app/code/Magento/ConfigurableProduct/Setup/InstallSchema.php
@@ -77,8 +77,7 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-                \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Super Attribute Table');
 
@@ -147,7 +146,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_super_attribute_id',
                 $installer->getTable('catalog_product_super_attribute'),
                 'product_super_attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -155,7 +153,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Super Attribute Label Table');
@@ -231,7 +228,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -244,7 +240,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_super_attribute_id',
                 $installer->getTable('catalog_product_super_attribute'),
                 'product_super_attribute_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Super Attribute Pricing Table');
@@ -300,7 +295,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -308,7 +302,6 @@ class InstallSchema implements InstallSchemaInterface
                 'parent_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Catalog Product Super Link Table');
diff --git a/app/code/Magento/Customer/Setup/InstallSchema.php b/app/code/Magento/Customer/Setup/InstallSchema.php
index d4a9815838c9e3d0d68a5795b6875cc034d8eac6..6f6750f3797043f4f25cfb78b4fd5e83bd0f0b6a 100644
--- a/app/code/Magento/Customer/Setup/InstallSchema.php
+++ b/app/code/Magento/Customer/Setup/InstallSchema.php
@@ -123,15 +123,13 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->addForeignKey(
             $installer->getFkName('customer_entity', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Customer Entity'
         );
@@ -262,7 +260,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -274,7 +271,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('customer_address_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -286,7 +282,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Address Entity Datetime'
@@ -350,7 +345,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -362,7 +356,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('customer_address_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -374,7 +367,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Address Entity Decimal'
@@ -438,21 +430,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_address_entity_int', 'entity_id', 'customer_address_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_address_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_address_entity_int', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Address Entity Int'
@@ -513,14 +502,12 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_address_entity_text', 'entity_id', 'customer_address_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_address_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -532,7 +519,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Address Entity Text'
@@ -596,7 +582,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -608,7 +593,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('customer_address_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -620,7 +604,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Address Entity Varchar'
@@ -684,21 +667,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_datetime', 'entity_id', 'customer_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_datetime', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Entity Datetime'
@@ -762,21 +742,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_decimal', 'entity_id', 'customer_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_decimal', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Entity Decimal'
@@ -840,21 +817,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_int', 'entity_id', 'customer_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_int', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Entity Int'
@@ -915,21 +889,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_text', 'entity_id', 'customer_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_text', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Entity Text'
@@ -993,21 +964,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_varchar', 'entity_id', 'customer_entity', 'entity_id'),
             'entity_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_entity_varchar', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Entity Varchar'
@@ -1100,7 +1068,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Eav Attribute'
@@ -1132,7 +1099,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Form Attribute'
@@ -1188,14 +1154,12 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('customer_eav_attribute_website', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Customer Eav Attribute Website'
diff --git a/app/code/Magento/DesignEditor/Setup/InstallSchema.php b/app/code/Magento/DesignEditor/Setup/InstallSchema.php
index e6a87de0bc1f10d3d7d8c2b03b881b0a62b90a10..d5edc3e7e86d98eec58a52b36111134615284f64 100644
--- a/app/code/Magento/DesignEditor/Setup/InstallSchema.php
+++ b/app/code/Magento/DesignEditor/Setup/InstallSchema.php
@@ -51,7 +51,6 @@ class InstallSchema implements InstallSchemaInterface
             'theme_id',
             $setup->getTable('theme'),
             'theme_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Design Editor Theme Change'
diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php
index 6d5c1720a2ce7b03dd418fb59139810ca3592116..dc2388e4e0c5606d3fbc3ff45c0a36d97d128da4 100644
--- a/app/code/Magento/Dhl/Model/Carrier.php
+++ b/app/code/Magento/Dhl/Model/Carrier.php
@@ -295,10 +295,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     /**
      * Collect and get rates
      *
-     * @param RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return bool|Result|null
      */
-    public function collectRates(RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag($this->_activeFlag)) {
             return false;
@@ -1255,10 +1255,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     /**
      * Processing additional validation to check is carrier applicable.
      *
-     * @param RateRequest $request
-     * @return $this|Error|boolean
+     * @param \Magento\Framework\Object $request
+     * @return $this|\Magento\Framework\Object|boolean
      */
-    public function proccessAdditionalValidation(RateRequest $request)
+    public function proccessAdditionalValidation(\Magento\Framework\Object $request)
     {
         //Skip by item validation if there is no items in request
         if (!count($this->getAllItems($request))) {
diff --git a/app/code/Magento/Directory/Setup/InstallSchema.php b/app/code/Magento/Directory/Setup/InstallSchema.php
index e28328894d0223e232d15ec445244cb4bdac5b2b..101ccd3ededc4c46b5f92e2950d0aa1e5abbb537 100644
--- a/app/code/Magento/Directory/Setup/InstallSchema.php
+++ b/app/code/Magento/Directory/Setup/InstallSchema.php
@@ -168,7 +168,6 @@ class InstallSchema implements InstallSchemaInterface
             'region_id',
             $installer->getTable('directory_country_region'),
             'region_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Directory Country Region Name'
diff --git a/app/code/Magento/Downloadable/Setup/InstallSchema.php b/app/code/Magento/Downloadable/Setup/InstallSchema.php
index 101da102b1418efda65a311856d4cb5ebb9ee6c5..e7043312e7a49331987f862339b2d8463041f45f 100644
--- a/app/code/Magento/Downloadable/Setup/InstallSchema.php
+++ b/app/code/Magento/Downloadable/Setup/InstallSchema.php
@@ -116,7 +116,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Downloadable Link Table');
@@ -164,7 +163,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_id',
                 $installer->getTable('downloadable_link'),
                 'link_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addIndex(
@@ -176,7 +174,6 @@ class InstallSchema implements InstallSchemaInterface
                 'website_id',
                 $installer->getTable('store_website'),
                 'website_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Downloadable Link Price Table');
@@ -274,16 +271,14 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_id',
                 $installer->getTable('customer_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->addForeignKey(
                 $installer->getFkName('downloadable_link_purchased', 'order_id', 'sales_order', 'entity_id'),
                 'order_id',
                 $installer->getTable('sales_order'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Downloadable Link Purchased Table');
         $installer->getConnection()->createTable($table);
@@ -427,7 +422,6 @@ class InstallSchema implements InstallSchemaInterface
                 'purchased_id',
                 $installer->getTable('downloadable_link_purchased'),
                 'purchased_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -440,8 +434,7 @@ class InstallSchema implements InstallSchemaInterface
                 'order_item_id',
                 $installer->getTable('sales_order_item'),
                 'item_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Downloadable Link Purchased Item Table');
         $installer->getConnection()->createTable($table);
@@ -493,7 +486,6 @@ class InstallSchema implements InstallSchemaInterface
                 'link_id',
                 $installer->getTable('downloadable_link'),
                 'link_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addIndex(
@@ -505,7 +497,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Link Title Table');
@@ -567,7 +558,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Downloadable Sample Table');
@@ -620,7 +610,6 @@ class InstallSchema implements InstallSchemaInterface
                 'sample_id',
                 $installer->getTable('downloadable_sample'),
                 'sample_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addIndex(
@@ -632,7 +621,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Downloadable Sample Title Table');
diff --git a/app/code/Magento/Eav/Setup/InstallSchema.php b/app/code/Magento/Eav/Setup/InstallSchema.php
index 9fb0d559cce5b8af7a54bfca2f6f7ecbb854e1a0..244cfe2d85e9e56e0e5771ef30b4c3b8888fbc0f 100644
--- a/app/code/Magento/Eav/Setup/InstallSchema.php
+++ b/app/code/Magento/Eav/Setup/InstallSchema.php
@@ -204,14 +204,12 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity'
@@ -281,21 +279,18 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('eav_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_datetime', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_datetime', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Value Prefix'
@@ -365,21 +360,18 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('eav_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_decimal', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_decimal', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Value Prefix'
@@ -449,21 +441,18 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('eav_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_int', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_int', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Value Prefix'
@@ -533,21 +522,18 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('eav_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_text', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_text', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Value Prefix'
@@ -617,21 +603,18 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('eav_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_varchar', 'entity_type_id', 'eav_entity_type', 'entity_type_id'),
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_varchar', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Value Prefix'
@@ -758,7 +741,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute'
@@ -811,14 +793,12 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_entity_store', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Store'
@@ -870,7 +850,6 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute Set'
@@ -940,7 +919,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_set_id',
             $installer->getTable('eav_attribute_set'),
             'attribute_set_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute Group'
@@ -1015,7 +993,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -1027,7 +1004,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_group_id',
             $installer->getTable('eav_attribute_group'),
             'attribute_group_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Entity Attributes'
@@ -1065,7 +1041,6 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute Option'
@@ -1112,14 +1087,12 @@ class InstallSchema implements InstallSchemaInterface
             'option_id',
             $installer->getTable('eav_attribute_option'),
             'option_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_attribute_option_value', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute Option Value'
@@ -1166,14 +1139,12 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_attribute_label', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Attribute Label'
@@ -1237,7 +1208,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Form Type'
@@ -1269,14 +1239,12 @@ class InstallSchema implements InstallSchemaInterface
             'entity_type_id',
             $installer->getTable('eav_entity_type'),
             'entity_type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_form_type_entity', 'type_id', 'eav_form_type', 'type_id'),
             'type_id',
             $installer->getTable('eav_form_type'),
             'type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Form Type Entity'
@@ -1325,7 +1293,6 @@ class InstallSchema implements InstallSchemaInterface
             'type_id',
             $installer->getTable('eav_form_type'),
             'type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Form Fieldset'
@@ -1363,14 +1330,12 @@ class InstallSchema implements InstallSchemaInterface
             'fieldset_id',
             $installer->getTable('eav_form_fieldset'),
             'fieldset_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_form_fieldset_label', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Form Fieldset Label'
@@ -1431,21 +1396,18 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('eav_form_element', 'fieldset_id', 'eav_form_fieldset', 'fieldset_id'),
             'fieldset_id',
             $installer->getTable('eav_form_fieldset'),
             'fieldset_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->addForeignKey(
             $installer->getFkName('eav_form_element', 'type_id', 'eav_form_type', 'type_id'),
             'type_id',
             $installer->getTable('eav_form_type'),
             'type_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Eav Form Element'
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 51ac852ac050d79893f68a4dc7a1d4fc47da9ad8..66f266dd1a8450611cba7a72e55e406a135e6caa 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -236,10 +236,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * Collect and get rates
      *
-     * @param RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return Result|bool|null
      */
-    public function collectRates(RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag($this->_activeFlag)) {
             return false;
diff --git a/app/code/Magento/GoogleOptimizer/Setup/InstallSchema.php b/app/code/Magento/GoogleOptimizer/Setup/InstallSchema.php
index a43eb599a8d722bbfafe95504703ee86c22c7ca8..e15c6b957e2231a9f9506f923c1f94d3b2c0dad9 100644
--- a/app/code/Magento/GoogleOptimizer/Setup/InstallSchema.php
+++ b/app/code/Magento/GoogleOptimizer/Setup/InstallSchema.php
@@ -78,7 +78,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Google Experiment code');
diff --git a/app/code/Magento/Integration/Setup/InstallSchema.php b/app/code/Magento/Integration/Setup/InstallSchema.php
index f3522a162f2fcb8776620150433a18c16cc09395..7c6bfda56692ba91f7ceb1170b00f28b055c88a4 100644
--- a/app/code/Magento/Integration/Setup/InstallSchema.php
+++ b/app/code/Magento/Integration/Setup/InstallSchema.php
@@ -211,21 +211,18 @@ class InstallSchema implements InstallSchemaInterface
             'admin_id',
             $adminTable,
             'user_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('oauth_token', 'consumer_id', 'oauth_consumer', 'entity_id'),
             'consumer_id',
             $installer->getTable('oauth_consumer'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('oauth_token', 'customer_id', 'customer_entity', 'entity_id'),
             'customer_id',
             $customerTable,
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'OAuth Tokens'
@@ -268,7 +265,6 @@ class InstallSchema implements InstallSchemaInterface
             'consumer_id',
             $installer->getTable('oauth_consumer'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'OAuth Nonce'
@@ -361,7 +357,6 @@ class InstallSchema implements InstallSchemaInterface
             'consumer_id',
             $installer->getTable('oauth_consumer'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         );
 
diff --git a/app/code/Magento/Log/Test/Unit/Model/VisitorTest.php b/app/code/Magento/Log/Test/Unit/Model/VisitorTest.php
index 79e8d2bee271fd48e1e5b4854aa768cfae68c73a..9e970f2c88c77e27dc2b866065d4ec62b617b610 100644
--- a/app/code/Magento/Log/Test/Unit/Model/VisitorTest.php
+++ b/app/code/Magento/Log/Test/Unit/Model/VisitorTest.php
@@ -122,13 +122,23 @@ class VisitorTest extends \PHPUnit_Framework_TestCase
     public function testGetFirstVisitAt()
     {
         $time = time();
-        $this->assertEquals($time, $this->visitor->getFirstVisitAt());
+        $this->assertEquals(
+            $time,
+            $this->visitor->getFirstVisitAt(),
+            'VisitorTest failed to assert the time for the first visit within 5 seconds.',
+            5
+        );
     }
 
     public function testGetLastVisitAt()
     {
         $time = time();
-        $this->assertEquals($time, $this->visitor->getLastVisitAt());
+        $this->assertEquals(
+            $time,
+            $this->visitor->getLastVisitAt(),
+            'VisitorTest failed to assert the time for the last visit within 5 seconds.',
+            5
+        );
     }
 
     public function testLogNewVisitor()
diff --git a/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Database.php b/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Database.php
index 6c77da1c9f7f4a7bd05d6f74ca3d476d20b03041..1d1c0c7224c383dd59a48ee93e017b7eaf9b80d8 100644
--- a/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Database.php
+++ b/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Database.php
@@ -109,7 +109,6 @@ class Database extends \Magento\MediaStorage\Model\Resource\File\Storage\Abstrac
             'directory_id',
             $dirStorageTable,
             'directory_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'File Storage'
diff --git a/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Directory/Database.php b/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Directory/Database.php
index 8291cd225711713be1671f237f6cd42998ddb55f..0ea6567f6404adc0630b0a132af105a0c1985bd5 100644
--- a/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Directory/Database.php
+++ b/app/code/Magento/MediaStorage/Model/Resource/File/Storage/Directory/Database.php
@@ -81,7 +81,6 @@ class Database extends \Magento\MediaStorage\Model\Resource\File\Storage\Abstrac
             'parent_id',
             $table,
             'directory_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Directory Storage'
diff --git a/app/code/Magento/Newsletter/Setup/InstallSchema.php b/app/code/Magento/Newsletter/Setup/InstallSchema.php
index 87ad2e8adcca1e752c396dccefc41423777758bd..f567558d0550f4ad4987a2b13d3418093c147c7c 100644
--- a/app/code/Magento/Newsletter/Setup/InstallSchema.php
+++ b/app/code/Magento/Newsletter/Setup/InstallSchema.php
@@ -92,8 +92,7 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Newsletter Subscriber');
         $installer->getConnection()->createTable($table);
@@ -293,7 +292,6 @@ class InstallSchema implements InstallSchemaInterface
                 'template_id',
                 $installer->getTable('newsletter_template'),
                 'template_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Newsletter Queue');
@@ -345,7 +343,6 @@ class InstallSchema implements InstallSchemaInterface
                 'queue_id',
                 $installer->getTable('newsletter_queue'),
                 'queue_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -358,7 +355,6 @@ class InstallSchema implements InstallSchemaInterface
                 'subscriber_id',
                 $installer->getTable('newsletter_subscriber'),
                 'subscriber_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Newsletter Queue Link');
@@ -392,7 +388,6 @@ class InstallSchema implements InstallSchemaInterface
                 'queue_id',
                 $installer->getTable('newsletter_queue'),
                 'queue_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -400,7 +395,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Newsletter Queue Store Link');
@@ -459,7 +453,6 @@ class InstallSchema implements InstallSchemaInterface
                 'queue_id',
                 $installer->getTable('newsletter_queue'),
                 'queue_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -467,7 +460,6 @@ class InstallSchema implements InstallSchemaInterface
                 'subscriber_id',
                 $installer->getTable('newsletter_subscriber'),
                 'subscriber_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Newsletter Problems');
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
index ff96421b77034d67dc4cf1cb6ab6c4d83077d3ad..d85a0d771d2fb3a8602b779c84ca27c9204efccf 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
@@ -55,12 +55,12 @@ class Flatrate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implement
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return Result|bool
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag('active')) {
             return false;
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
index 0586b180b8832ae34b16ca6267c77dab93df82e4..fdbc3c264671dfe4714d0f003a48d54efcba85dc 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
@@ -58,10 +58,10 @@ class Freeshipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier imple
     /**
      * FreeShipping Rates Collector
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return \Magento\Shipping\Model\Rate\Result|bool
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag('active')) {
             return false;
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
index e1411217d1d5d1b96dae3cfd82ee4ba78047b4b1..40df2042c043dbb3782b0d3e6b8f3d6a1d304734 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
@@ -50,11 +50,11 @@ class Pickup extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return \Magento\Shipping\Model\Rate\Result
      * @SuppressWarnings(PHPMD.UnusedLocalVariable)
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag('active')) {
             return false;
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
index 4456feee0578c38c56347f4ec2f474d5d5d765fa..21c1fc1cf75899ce1fdbb49c15e31c9865d57c32 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
@@ -72,13 +72,13 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return \Magento\Shipping\Model\Rate\Result
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag('active')) {
             return false;
diff --git a/app/code/Magento/Payment/Model/Cart.php b/app/code/Magento/Payment/Model/Cart.php
index 85962afa760aac013aa161f98e21225336030a10..436bdc899a48d198278823bd4ec1c381384d6447 100644
--- a/app/code/Magento/Payment/Model/Cart.php
+++ b/app/code/Magento/Payment/Model/Cart.php
@@ -75,7 +75,7 @@ class Cart
     /**
      * @param \Magento\Payment\Model\Cart\SalesModel\Factory $salesModelFactory
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Sales\Model\Order|\Magento\Quote\Model\Quote $salesModel
+     * @param \Magento\Quote\Api\Data\CartInterface $salesModel
      */
     public function __construct(
         \Magento\Payment\Model\Cart\SalesModel\Factory $salesModelFactory,
@@ -91,6 +91,7 @@ class Cart
      * Return payment cart sales model
      *
      * @return \Magento\Payment\Model\Cart\SalesModel\SalesModelInterface
+     * @api
      */
     public function getSalesModel()
     {
@@ -102,6 +103,7 @@ class Cart
      *
      * @param float $taxAmount
      * @return void
+     * @api
      */
     public function addTax($taxAmount)
     {
@@ -113,6 +115,7 @@ class Cart
      *
      * @param float $taxAmount
      * @return void
+     * @api
      */
     public function setTax($taxAmount)
     {
@@ -123,6 +126,7 @@ class Cart
      * Get tax amount
      *
      * @return float
+     * @api
      */
     public function getTax()
     {
@@ -134,6 +138,7 @@ class Cart
      *
      * @param float $discountAmount
      * @return void
+     * @api
      */
     public function addDiscount($discountAmount)
     {
@@ -145,6 +150,7 @@ class Cart
      *
      * @param float $discountAmount
      * @return void
+     * @api
      */
     public function setDiscount($discountAmount)
     {
@@ -155,6 +161,7 @@ class Cart
      * Get discount amount
      *
      * @return float
+     * @api
      */
     public function getDiscount()
     {
@@ -166,6 +173,7 @@ class Cart
      *
      * @param float $shippingAmount
      * @return void
+     * @api
      */
     public function addShipping($shippingAmount)
     {
@@ -177,6 +185,7 @@ class Cart
      *
      * @param float $shippingAmount
      * @return void
+     * @api
      */
     public function setShipping($shippingAmount)
     {
@@ -187,6 +196,7 @@ class Cart
      * Get shipping amount
      *
      * @return float
+     * @api
      */
     public function getShipping()
     {
@@ -198,6 +208,7 @@ class Cart
      *
      * @param float $subtotalAmount
      * @return void
+     * @api
      */
     public function addSubtotal($subtotalAmount)
     {
@@ -208,6 +219,7 @@ class Cart
      * Get subtotal amount
      *
      * @return float
+     * @api
      */
     public function getSubtotal()
     {
@@ -222,6 +234,7 @@ class Cart
      * @param float $amount
      * @param string|null $identifier
      * @return void
+     * @api
      */
     public function addCustomItem($name, $qty, $amount, $identifier = null)
     {
@@ -232,6 +245,7 @@ class Cart
      * Get all cart items
      *
      * @return array
+     * @api
      */
     public function getAllItems()
     {
@@ -243,6 +257,7 @@ class Cart
      * Get shipping, tax, subtotal and discount amounts all together
      *
      * @return array
+     * @api
      */
     public function getAmounts()
     {
@@ -255,6 +270,7 @@ class Cart
      * Specify that shipping should be transferred as cart item
      *
      * @return void
+     * @api
      */
     public function setTransferShippingAsItem()
     {
@@ -265,6 +281,7 @@ class Cart
      * Specify that discount should be transferred as cart item
      *
      * @return void
+     * @api
      */
     public function setTransferDiscountAsItem()
     {
diff --git a/app/code/Magento/Payment/Model/Cart/SalesModel/Factory.php b/app/code/Magento/Payment/Model/Cart/SalesModel/Factory.php
index 186a6fc45f5c8dc0ffe77e8f31aa54476da796ba..f077e1a72f1870943e626cbcc0dc41c1062c9ac6 100644
--- a/app/code/Magento/Payment/Model/Cart/SalesModel/Factory.php
+++ b/app/code/Magento/Payment/Model/Cart/SalesModel/Factory.php
@@ -26,7 +26,7 @@ class Factory
     /**
      * Wrap sales model with Magento\Payment\Model\Cart\SalesModel\SalesModelInterface
      *
-     * @param \Magento\Sales\Model\Order|\Magento\Quote\Model\Quote $salesModel
+     * @param \Magento\Quote\Api\Data\CartInterface $salesModel
      * @return \Magento\Payment\Model\Cart\SalesModel\SalesModelInterface
      * @throws \InvalidArgumentException
      */
diff --git a/app/code/Magento/Payment/Model/Cart/SalesModel/SalesModelInterface.php b/app/code/Magento/Payment/Model/Cart/SalesModel/SalesModelInterface.php
index 117eb8b1d48e2ba5fd61cf5c504e67f6730c7003..a210f55bb3a2b3f7cb6a7d75d92377bac6070b17 100644
--- a/app/code/Magento/Payment/Model/Cart/SalesModel/SalesModelInterface.php
+++ b/app/code/Magento/Payment/Model/Cart/SalesModel/SalesModelInterface.php
@@ -14,26 +14,31 @@ interface SalesModelInterface
      * Get all items from shopping sales model
      *
      * @return array
+     * @api
      */
     public function getAllItems();
 
     /**
      * @return float|null
+     * @api
      */
     public function getBaseSubtotal();
 
     /**
      * @return float|null
+     * @api
      */
     public function getBaseTaxAmount();
 
     /**
      * @return float|null
+     * @api
      */
     public function getBaseShippingAmount();
 
     /**
      * @return float|null
+     * @api
      */
     public function getBaseDiscountAmount();
 
@@ -43,13 +48,15 @@ interface SalesModelInterface
      * @param string $key
      * @param mixed $args
      * @return mixed
+     * @api
      */
     public function getDataUsingMethod($key, $args = null);
 
     /**
      * Return object that contains tax related fields
      *
-     * @return \Magento\Sales\Model\Order|\Magento\Quote\Model\Quote\Address
+     * @return \Magento\Sales\Api\Data\OrderInterface|\Magento\Quote\Api\Data\AddressInterface
+     * @api
      */
     public function getTaxContainer();
 }
diff --git a/app/code/Magento/Payment/Model/Checks/PaymentMethodChecksInterface.php b/app/code/Magento/Payment/Model/Checks/PaymentMethodChecksInterface.php
index d2bb13d0eda1823369883e738efa3888c7507b65..9d2ad43801e5ebda0834b4c4adff7019e4631b65 100644
--- a/app/code/Magento/Payment/Model/Checks/PaymentMethodChecksInterface.php
+++ b/app/code/Magento/Payment/Model/Checks/PaymentMethodChecksInterface.php
@@ -14,6 +14,7 @@ interface PaymentMethodChecksInterface
      * Retrieve payment method code
      *
      * @return string
+     * @api
      */
     public function getCode();
 
@@ -22,6 +23,7 @@ interface PaymentMethodChecksInterface
      * Can be used in admin
      *
      * @return bool
+     * @api
      */
     public function canUseInternal();
 
@@ -29,6 +31,7 @@ interface PaymentMethodChecksInterface
      * Can be used in regular checkout
      *
      * @return bool
+     * @api
      */
     public function canUseCheckout();
 
@@ -37,6 +40,7 @@ interface PaymentMethodChecksInterface
      *
      * @param string $country
      * @return bool
+     * @api
      */
     public function canUseForCountry($country);
 
@@ -45,6 +49,7 @@ interface PaymentMethodChecksInterface
      *
      * @param string $currencyCode
      * @return bool
+     * @api
      */
     public function canUseForCurrency($currencyCode);
 
@@ -55,6 +60,7 @@ interface PaymentMethodChecksInterface
      * @param int|string|null|\Magento\Store\Model\Store $storeId
      *
      * @return mixed
+     * @api
      */
     public function getConfigData($field, $storeId = null);
 }
diff --git a/app/code/Magento/Payment/Model/Config.php b/app/code/Magento/Payment/Model/Config.php
index 62a196bfce79f0b267fea1af1edc2cbf5dd35097..9d782ce97998d70e2a78f63ecd92a51fa7a1a2ed 100644
--- a/app/code/Magento/Payment/Model/Config.php
+++ b/app/code/Magento/Payment/Model/Config.php
@@ -86,6 +86,7 @@ class Config
      * Retrieve active system payments
      *
      * @return array
+     * @api
      */
     public function getActiveMethods()
     {
@@ -107,6 +108,7 @@ class Config
      * Get list of credit card types
      *
      * @return array
+     * @api
      */
     public function getCcTypes()
     {
@@ -117,6 +119,7 @@ class Config
      * Retrieve array of payment methods information
      *
      * @return array
+     * @api
      */
     public function getMethodsInfo()
     {
@@ -127,6 +130,7 @@ class Config
      * Get payment groups
      *
      * @return array
+     * @api
      */
     public function getGroups()
     {
@@ -137,6 +141,7 @@ class Config
      * Retrieve list of months translation
      *
      * @return array
+     * @api
      */
     public function getMonths()
     {
@@ -155,6 +160,7 @@ class Config
      * Retrieve array of available years
      *
      * @return array
+     * @api
      */
     public function getYears()
     {
diff --git a/app/code/Magento/Payment/Model/InfoInterface.php b/app/code/Magento/Payment/Model/InfoInterface.php
index 270ee9c16fe89c98208ec2f8ac1cde356adae12b..b39670441cf23d5fd320c6faf98f421ee39b5321 100644
--- a/app/code/Magento/Payment/Model/InfoInterface.php
+++ b/app/code/Magento/Payment/Model/InfoInterface.php
@@ -16,6 +16,7 @@ interface InfoInterface
      *
      * @param string $data
      * @return string
+     * @api
      */
     public function encrypt($data);
 
@@ -24,6 +25,7 @@ interface InfoInterface
      *
      * @param string $data
      * @return string
+     * @api
      */
     public function decrypt($data);
 
@@ -33,6 +35,7 @@ interface InfoInterface
      * @param string $key
      * @param string|null $value
      * @return mixed
+     * @api
      */
     public function setAdditionalInformation($key, $value = null);
 
@@ -41,6 +44,7 @@ interface InfoInterface
      *
      * @param mixed|null $key
      * @return bool
+     * @api
      */
     public function hasAdditionalInformation($key = null);
 
@@ -49,6 +53,7 @@ interface InfoInterface
      *
      * @param string|null $key
      * @return $this
+     * @api
      */
     public function unsAdditionalInformation($key = null);
 
@@ -57,6 +62,7 @@ interface InfoInterface
      *
      * @param string|null $key
      * @return mixed
+     * @api
      */
     public function getAdditionalInformation($key = null);
 
@@ -65,6 +71,7 @@ interface InfoInterface
      *
      * @return \Magento\Payment\Model\MethodInterface
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function getMethodInstance();
 }
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index 74e26082b6c0b7525c47b07c57f5c6cf08bc263d..e316982a1be7081f470bc8cb2493d19ea0debfea 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -260,6 +260,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check order availability
      *
      * @return bool
+     * @api
      */
     public function canOrder()
     {
@@ -270,6 +271,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check authorize availability
      *
      * @return bool
+     * @api
      */
     public function canAuthorize()
     {
@@ -280,6 +282,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check capture availability
      *
      * @return bool
+     * @api
      */
     public function canCapture()
     {
@@ -290,6 +293,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check partial capture availability
      *
      * @return bool
+     * @api
      */
     public function canCapturePartial()
     {
@@ -300,6 +304,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check whether capture can be performed once and no further capture possible
      *
      * @return bool
+     * @api
      */
     public function canCaptureOnce()
     {
@@ -310,6 +315,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check refund availability
      *
      * @return bool
+     * @api
      */
     public function canRefund()
     {
@@ -320,6 +326,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check partial refund availability for invoice
      *
      * @return bool
+     * @api
      */
     public function canRefundPartialPerInvoice()
     {
@@ -332,6 +339,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param   \Magento\Framework\Object $payment
      * @return  bool
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function canVoid(\Magento\Framework\Object $payment)
     {
@@ -363,6 +371,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Can be edit order (renew order)
      *
      * @return bool
+     * @api
      */
     public function canEdit()
     {
@@ -373,6 +382,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Check fetch transaction info availability
      *
      * @return bool
+     * @api
      */
     public function canFetchTransactionInfo()
     {
@@ -386,6 +396,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param string $transactionId
      * @return array
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payment, $transactionId)
     {
@@ -396,6 +407,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Retrieve payment system relation flag
      *
      * @return bool
+     * @api
      */
     public function isGateway()
     {
@@ -406,6 +418,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Retrieve payment method online/offline flag
      *
      * @return bool
+     * @api
      */
     public function isOffline()
     {
@@ -416,6 +429,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Flag if we need to run payment initialize while order place
      *
      * @return bool
+     * @api
      */
     public function isInitializeNeeded()
     {
@@ -482,6 +496,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Retrieve block type for display method information
      *
      * @return string
+     * @api
      */
     public function getInfoBlockType()
     {
@@ -491,8 +506,9 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
     /**
      * Retrieve payment information model object
      *
-     * @return \Magento\Payment\Model\Info
+     * @return \Magento\Payment\Model\InfoInterface
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function getInfoInstance()
     {
@@ -508,6 +524,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function validate()
     {
@@ -537,6 +554,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function order(\Magento\Framework\Object $payment, $amount)
     {
@@ -555,6 +573,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function authorize(\Magento\Framework\Object $payment, $amount)
     {
@@ -573,6 +592,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function capture(\Magento\Framework\Object $payment, $amount)
     {
@@ -591,6 +611,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param Invoice $invoice
      * @param Payment $payment
      * @return $this
+     * @api
      */
     public function processInvoice($invoice, $payment)
     {
@@ -606,6 +627,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param Invoice $invoice
      * @param Payment $payment
      * @return $this
+     * @api
      */
     public function processBeforeRefund($invoice, $payment)
     {
@@ -621,6 +643,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function refund(\Magento\Framework\Object $payment, $amount)
     {
@@ -635,6 +658,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
      * @param Payment $payment
      * @return $this
+     * @api
      */
     public function processCreditmemo($creditmemo, $payment)
     {
@@ -649,6 +673,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @return $this
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function cancel(\Magento\Framework\Object $payment)
     {
@@ -661,6 +686,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param \Magento\Framework\Object $payment
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function void(\Magento\Framework\Object $payment)
     {
@@ -676,6 +702,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param \Magento\Payment\Model\InfoInterface $payment
      * @return bool
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function canReviewPayment(\Magento\Payment\Model\InfoInterface $payment)
     {
@@ -688,6 +715,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param \Magento\Payment\Model\InfoInterface $payment
      * @return false
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function acceptPayment(\Magento\Payment\Model\InfoInterface $payment)
     {
@@ -703,6 +731,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * @param \Magento\Payment\Model\InfoInterface $payment
      * @return false
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @api
      */
     public function denyPayment(\Magento\Payment\Model\InfoInterface $payment)
     {
@@ -744,6 +773,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @param array|\Magento\Framework\Object $data
      * @return $this
+     * @api
      */
     public function assignData($data)
     {
@@ -759,6 +789,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Prepare info instance for save
      *
      * @return $this
+     * @api
      */
     public function prepareSave()
     {
@@ -768,9 +799,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
     /**
      * Check whether payment method can be used
      *
-     * TODO: payment method instance is not supposed to know about quote
-     *
-     * @param \Magento\Quote\Model\Quote|null $quote
+     * @param \Magento\Quote\Api\Data\CartInterface|null $quote
      * @return bool
      */
     public function isAvailable($quote = null)
@@ -797,6 +826,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @return $this
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function initialize($paymentAction, $stateObject)
     {
@@ -808,6 +838,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      * Used to universalize payment actions when processing payment place
      *
      * @return string
+     * @api
      */
     public function getConfigPaymentAction()
     {
@@ -832,6 +863,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @return bool
      * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * @api
      */
     public function getDebugFlag()
     {
@@ -843,6 +875,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
      *
      * @param mixed $debugData
      * @return void
+     * @api
      */
     public function debugData($debugData)
     {
diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php
index 167f88c7e9fca09662aaad2148ed7c3599c210f9..978e75c5840aaeae528aad5111f93b3c77fc75c5 100644
--- a/app/code/Magento/Payment/Model/Method/Cc.php
+++ b/app/code/Magento/Payment/Model/Method/Cc.php
@@ -250,6 +250,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
 
     /**
      * @return bool
+     * @api
      */
     public function hasVerification()
     {
@@ -262,6 +263,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
 
     /**
      * @return array
+     * @api
      */
     public function getVerificationRegEx()
     {
@@ -298,6 +300,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
     /**
      * @param string $type
      * @return bool
+     * @api
      */
     public function otherCcType($type)
     {
@@ -309,6 +312,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
      *
      * @param   string $ccNumber
      * @return  bool
+     * @api
      */
     public function validateCcNum($ccNumber)
     {
@@ -348,6 +352,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
      *
      * @param string $ccNumber
      * @return bool
+     * @api
      */
     public function validateCcNumOther($ccNumber)
     {
@@ -357,7 +362,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
     /**
      * Check whether there are CC types set in configuration
      *
-     * @param \Magento\Quote\Model\Quote|null $quote
+     * @param \Magento\Quote\Api\Data\CartInterface|null $quote
      * @return bool
      */
     public function isAvailable($quote = null)
diff --git a/app/code/Magento/Payment/Model/MethodInterface.php b/app/code/Magento/Payment/Model/MethodInterface.php
index 0e6c1da86887622a33d98efeb2df06b65e14741b..f800703d73e3cf04cbbd8294c70262e5fb60ae0a 100644
--- a/app/code/Magento/Payment/Model/MethodInterface.php
+++ b/app/code/Magento/Payment/Model/MethodInterface.php
@@ -15,6 +15,7 @@ interface MethodInterface
      * Retrieve payment method code
      *
      * @return string
+     * @api
      */
     public function getCode();
 
@@ -22,6 +23,7 @@ interface MethodInterface
      * Retrieve block type for method form generation
      *
      * @return string
+     * @api
      */
     public function getFormBlockType();
 
@@ -29,6 +31,7 @@ interface MethodInterface
      * Retrieve payment method title
      *
      * @return string
+     * @api
      */
     public function getTitle();
 }
diff --git a/app/code/Magento/Payment/Model/MethodList.php b/app/code/Magento/Payment/Model/MethodList.php
index 8ba8a76d77acc33da2bb8e9c2f1423776ed76313..5d486411b9f7a8d63139579ff76d55d13e26ccb8 100644
--- a/app/code/Magento/Payment/Model/MethodList.php
+++ b/app/code/Magento/Payment/Model/MethodList.php
@@ -33,10 +33,11 @@ class MethodList
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote $quote
+     * @param \Magento\Quote\Api\Data\CartInterface $quote
      * @return \Magento\Payment\Model\MethodInterface[]
+     * @api
      */
-    public function getAvailableMethods(\Magento\Quote\Model\Quote $quote = null)
+    public function getAvailableMethods(\Magento\Quote\Api\Data\CartInterface $quote = null)
     {
         $store = $quote ? $quote->getStoreId() : null;
         $methods = [];
@@ -54,10 +55,10 @@ class MethodList
      * Check payment method model
      *
      * @param \Magento\Payment\Model\MethodInterface $method
-     * @param \Magento\Quote\Model\Quote $quote
+     * @param \Magento\Quote\Api\Data\CartInterface $quote
      * @return bool
      */
-    protected function _canUseMethod($method, \Magento\Quote\Model\Quote $quote)
+    protected function _canUseMethod($method, \Magento\Quote\Api\Data\CartInterface $quote)
     {
         return $this->methodSpecificationFactory->create(
             [
diff --git a/app/code/Magento/ProductAlert/Setup/InstallSchema.php b/app/code/Magento/ProductAlert/Setup/InstallSchema.php
index 6b8e6b732f368e00e1b40579d23956c81578dc06..8ccda0176f7682591e0a283f97287450c331ae2d 100644
--- a/app/code/Magento/ProductAlert/Setup/InstallSchema.php
+++ b/app/code/Magento/ProductAlert/Setup/InstallSchema.php
@@ -97,21 +97,18 @@ class InstallSchema implements InstallSchemaInterface
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('product_alert_price', 'product_id', 'catalog_product_entity', 'entity_id'),
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('product_alert_price', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Product Alert Price'
@@ -185,21 +182,18 @@ class InstallSchema implements InstallSchemaInterface
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('product_alert_stock', 'customer_id', 'customer_entity', 'entity_id'),
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('product_alert_stock', 'product_id', 'catalog_product_entity', 'entity_id'),
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Product Alert Stock'
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 1d663cfd5d942c84d88a63f9161cdc9773f2c4aa..88010642002f69ba6d36ff56c882fd2f96076ccd 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -2253,12 +2253,6 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     {
         if (!$this->getReservedOrderId()) {
             $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this));
-        } else {
-            //checking if reserved order id was already used for some order
-            //if yes reserving new one if not using old one
-            if ($this->_getResource()->isOrderIncrementIdUsed($this->getReservedOrderId())) {
-                $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this));
-            }
         }
         return $this;
     }
diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php
index c57a8d0d5e8163661cdb1e240d60924801c3e5bb..4cddfa347659b75a2930348d1fb19cf54bf3226c 100644
--- a/app/code/Magento/Quote/Model/Quote/Address.php
+++ b/app/code/Magento/Quote/Model/Quote/Address.php
@@ -248,7 +248,7 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
      * @param \Magento\Quote\Model\Quote\Address\Total\CollectorFactory $totalCollectorFactory
      * @param Address\TotalFactory $addressTotalFactory
      * @param \Magento\Framework\Object\Copy $objectCopyService
-     * @param Address\CarrierFactoryInterface $carrierFactory
+     * @param \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory
      * @param Address\Validator $validator
      * @param \Magento\Customer\Model\Address\Mapper $addressMapper
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -280,7 +280,7 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
         \Magento\Quote\Model\Quote\Address\Total\CollectorFactory $totalCollectorFactory,
         \Magento\Quote\Model\Quote\Address\TotalFactory $addressTotalFactory,
         \Magento\Framework\Object\Copy $objectCopyService,
-        \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface $carrierFactory,
+        \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory,
         Address\Validator $validator,
         \Magento\Customer\Model\Address\Mapper $addressMapper,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
diff --git a/app/code/Magento/Quote/Model/Quote/Address/ToOrder.php b/app/code/Magento/Quote/Model/Quote/Address/ToOrder.php
index 6f58b342a667a7b0a56dee8e649007f5710ddfba..3b4649c44736fce125edcde2e664247dd5a22411 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/ToOrder.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/ToOrder.php
@@ -75,7 +75,8 @@ class ToOrder
             '\Magento\Sales\Api\Data\OrderInterface'
         );
         $order->setStoreId($object->getQuote()->getStoreId())
-            ->setQuoteId($object->getQuote()->getId());
+            ->setQuoteId($object->getQuote()->getId())
+            ->setIncrementId($object->getQuote()->getReservedOrderId());
 
         $this->objectCopyService->copyFieldsetToTarget('sales_convert_quote', 'to_order', $object->getQuote(), $order);
         $this->eventManager->dispatch(
diff --git a/app/code/Magento/Quote/Model/Resource/Quote.php b/app/code/Magento/Quote/Model/Resource/Quote.php
index 4483f59150e89ab68d768e1971b2507ce8461194..990902300124466ee9cdc4a3437425e9f5841156 100644
--- a/app/code/Magento/Quote/Model/Resource/Quote.php
+++ b/app/code/Magento/Quote/Model/Resource/Quote.php
@@ -16,22 +16,22 @@ use Magento\Framework\Model\Resource\Db\AbstractDb;
 class Quote extends AbstractDb
 {
     /**
-     * @var \Magento\Eav\Model\Config
+     * @var \Magento\SalesSequence\Model\Manager
      */
-    protected $_config;
+    protected $sequenceManager;
 
     /**
      * @param \Magento\Framework\Model\Resource\Db\Context $context
-     * @param \Magento\Eav\Model\Config $config
-     * @param string|null $resourcePrefix
+     * @param \Magento\SalesSequence\Model\Manager $sequenceManager
+     * @param null $resourcePrefix
      */
     public function __construct(
         \Magento\Framework\Model\Resource\Db\Context $context,
-        \Magento\Eav\Model\Config $config,
+        \Magento\SalesSequence\Model\Manager $sequenceManager,
         $resourcePrefix = null
     ) {
         parent::__construct($context, $resourcePrefix);
-        $this->_config = $config;
+        $this->sequenceManager = $sequenceManager;
     }
 
     /**
@@ -156,28 +156,8 @@ class Quote extends AbstractDb
      */
     public function getReservedOrderId($quote)
     {
-        $storeId = (int)$quote->getStoreId();
-        return $this->_config->getEntityType(\Magento\Sales\Model\Order::ENTITY)->fetchNewIncrementId($storeId);
-    }
-
-    /**
-     * Check is order increment id use in sales/order table
-     *
-     * @param int $orderIncrementId
-     * @return bool
-     */
-    public function isOrderIncrementIdUsed($orderIncrementId)
-    {
-        $adapter = $this->_getReadAdapter();
-        $bind = [':increment_id' => $orderIncrementId];
-        $select = $adapter->select();
-        $select->from($this->getTable('sales_order'), 'entity_id')->where('increment_id = :increment_id');
-        $entity_id = $adapter->fetchOne($select, $bind);
-        if ($entity_id > 0) {
-            return true;
-        }
-
-        return false;
+        return $this->sequenceManager->getSequence(\Magento\Sales\Model\Order::ENTITY, (int)$quote->getStoreId())
+            ->getNextValue();
     }
 
     /**
diff --git a/app/code/Magento/Quote/Model/Resource/Quote/Address/Rate/Collection.php b/app/code/Magento/Quote/Model/Resource/Quote/Address/Rate/Collection.php
index 6801bb83f5e43e43ad241ac5fed14dae285e9302..f21945483c6873facccac4eb9efeebe611ba723c 100644
--- a/app/code/Magento/Quote/Model/Resource/Quote/Address/Rate/Collection.php
+++ b/app/code/Magento/Quote/Model/Resource/Quote/Address/Rate/Collection.php
@@ -24,7 +24,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface $carrierFactory
+     * @param \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory
      * @param \Zend_Db_Adapter_Abstract $connection
      * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
      */
@@ -33,7 +33,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Quote\Model\Quote\Address\CarrierFactoryInterface $carrierFactory,
+        \Magento\Shipping\Model\CarrierFactoryInterface $carrierFactory,
         $connection = null,
         \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
diff --git a/app/code/Magento/Quote/Setup/InstallSchema.php b/app/code/Magento/Quote/Setup/InstallSchema.php
index 5e736acaaabe153a06ad2ff08fb848204673a164..7e9947028060c0ec596393146748c4e5907b7789 100644
--- a/app/code/Magento/Quote/Setup/InstallSchema.php
+++ b/app/code/Magento/Quote/Setup/InstallSchema.php
@@ -334,7 +334,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote'
@@ -684,7 +683,6 @@ class InstallSchema implements InstallSchemaInterface
             'quote_id',
             $installer->getTable('quote'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote Address'
@@ -965,29 +963,25 @@ class InstallSchema implements InstallSchemaInterface
             'parent_item_id',
             $installer->getTable('quote_item'),
             'item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('quote_item', 'product_id', 'catalog_product_entity', 'entity_id'),
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('quote_item', 'quote_id', 'quote', 'entity_id'),
             'quote_id',
             $installer->getTable('quote'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('quote_item', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Quote Item'
         );
@@ -1245,7 +1239,6 @@ class InstallSchema implements InstallSchemaInterface
             'quote_address_id',
             $installer->getTable('quote_address'),
             'address_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -1257,14 +1250,12 @@ class InstallSchema implements InstallSchemaInterface
             'parent_item_id',
             $installer->getTable('quote_address_item'),
             'address_item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('quote_address_item', 'quote_item_id', 'quote_item', 'item_id'),
             'quote_item_id',
             $installer->getTable('quote_item'),
             'item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote Address Item'
@@ -1314,7 +1305,6 @@ class InstallSchema implements InstallSchemaInterface
             'item_id',
             $installer->getTable('quote_item'),
             'item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote Item Option'
@@ -1448,7 +1438,6 @@ class InstallSchema implements InstallSchemaInterface
             'quote_id',
             $installer->getTable('quote'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote Payment'
@@ -1540,7 +1529,6 @@ class InstallSchema implements InstallSchemaInterface
             'address_id',
             $installer->getTable('quote_address'),
             'address_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Quote Shipping Rate'
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/ToOrderTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/ToOrderTest.php
index 8dea99e3bed4cc480d50780aff182647a8d95a37..0859ec68fe7bde8d106915f6a98a7c013813872b 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/ToOrderTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/ToOrderTest.php
@@ -84,7 +84,7 @@ class ToOrderTest extends \PHPUnit_Framework_TestCase
 
         $object = $this->getMock('Magento\Quote\Model\Quote\Address', [], [], '', false);
         $quote = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
-        $object->expects($this->exactly(4))->method('getQuote')->willReturn($quote);
+        $object->expects($this->exactly(5))->method('getQuote')->willReturn($quote);
         $quote->expects($this->once())->method('getId')->willReturn($quoteId);
         $quote->expects($this->once())->method('getStoreId')->willReturn($storeId);
         $this->objectCopyMock->expects($this->once())->method('getDataFromFieldset')->with(
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Resource/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/Resource/QuoteTest.php
deleted file mode 100644
index 33885a47c6bb30365fdff0b0ca2ed287dc4a2bf8..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Test/Unit/Model/Resource/QuoteTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Test\Unit\Model\Resource;
-
-class QuoteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Quote\Model\Resource\Quote
-     */
-    protected $model;
-
-    /**
-     * @var \Magento\Framework\App\Resource
-     */
-    protected $resourceMock;
-
-    /**
-     * @var \Magento\Eav\Model\Config
-     */
-    protected $configMock;
-
-    /**
-     * @var \Magento\Framework\DB\Adapter\Pdo\Mysql
-     */
-    protected $adapterMock;
-
-    /**
-     * @var \Magento\Framework\DB\Select
-     */
-    protected $selectMock;
-
-    protected function setUp()
-    {
-        $this->selectMock = $this->getMock('\Magento\Framework\DB\Select', [], [], '', false);
-        $this->selectMock->expects($this->any())->method('from')->will($this->returnSelf());
-        $this->selectMock->expects($this->any())->method('where');
-
-        $this->adapterMock = $this->getMock('\Magento\Framework\DB\Adapter\Pdo\Mysql', [], [], '', false);
-        $this->adapterMock->expects($this->any())->method('select')->will($this->returnValue($this->selectMock));
-
-        $this->resourceMock = $this->getMock('\Magento\Framework\App\Resource', [], [], '', false);
-        $this->resourceMock->expects(
-            $this->any()
-        )->method(
-            'getConnection'
-        )->will(
-            $this->returnValue($this->adapterMock)
-        );
-
-        $this->configMock = $this->getMock('\Magento\Eav\Model\Config', [], [], '', false);
-
-        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
-        $contextMock->expects($this->once())->method('getResources')->willReturn($this->resourceMock);
-
-        $this->model = new \Magento\Quote\Model\Resource\Quote(
-            $contextMock,
-            $this->configMock
-        );
-    }
-
-    /**
-     * @param $value
-     * @dataProvider isOrderIncrementIdUsedDataProvider
-     */
-    public function testIsOrderIncrementIdUsed($value)
-    {
-        $expectedBind = [':increment_id' => $value];
-        $this->adapterMock->expects($this->once())->method('fetchOne')->with($this->selectMock, $expectedBind);
-        $this->model->isOrderIncrementIdUsed($value);
-    }
-
-    /**
-     * @return array
-     */
-    public function isOrderIncrementIdUsedDataProvider()
-    {
-        return [[100000001], ['10000000001'], ['M10000000001']];
-    }
-}
diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json
index 2d867ccca552b0bf3dee8361003601c036092d3a..173e239f796d8072845d23365a02360f0f45a16d 100644
--- a/app/code/Magento/Quote/composer.json
+++ b/app/code/Magento/Quote/composer.json
@@ -10,6 +10,8 @@
         "magento/module-authorization": "0.74.0-beta4",
         "magento/module-payment": "0.74.0-beta4",
         "magento/module-sales": "0.74.0-beta4",
+        "magento/module-shipping": "0.74.0-beta4",
+        "magento/module-sales-sequence": "0.74.0-beta4",
         "magento/module-backend": "0.74.0-beta4",
         "magento/module-directory": "0.74.0-beta4",
         "magento/module-eav": "0.74.0-beta4",
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product/Grid.php b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product/Grid.php
index 6de66a60e04a8c28d281e4f55f1fb0cca6a388dc..347405789dc2e49d5131525a55b1ec3aebbe4b29 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product/Grid.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product/Grid.php
@@ -57,14 +57,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
     protected function _prepareCollection()
     {
         $collection = $this->_quotesFactory->create();
-        if ($this->queryResolver->isSingleQuery()) {
-            $collection->prepareForProductsInCarts();
-            $collection->setSelectCountSqlType(
-                \Magento\Reports\Model\Resource\Quote\Collection::SELECT_COUNT_SQL_TYPE_CART
-            );
-        } else {
-            $collection->prepareActiveCartItems();
-        }
+        $collection->prepareActiveCartItems();
         $this->setCollection($collection);
         return parent::_prepareCollection();
     }
@@ -80,6 +73,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
                 'header' => __('ID'),
                 'align' => 'right',
                 'index' => 'entity_id',
+                'sortable' => false,
                 'header_css_class' => 'col-id',
                 'column_css_class' => 'col-id'
             ]
@@ -90,6 +84,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
             [
                 'header' => __('Product'),
                 'index' => 'name',
+                'sortable' => false,
                 'header_css_class' => 'col-product',
                 'column_css_class' => 'col-product'
             ]
@@ -104,6 +99,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
                 'type' => 'currency',
                 'currency_code' => $currencyCode,
                 'index' => 'price',
+                'sortable' => false,
                 'renderer' => 'Magento\Reports\Block\Adminhtml\Grid\Column\Renderer\Currency',
                 'rate' => $this->getRate($currencyCode),
                 'header_css_class' => 'col-price',
@@ -117,6 +113,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
                 'header' => __('Carts'),
                 'align' => 'right',
                 'index' => 'carts',
+                'sortable' => false,
                 'header_css_class' => 'col-carts',
                 'column_css_class' => 'col-carts'
             ]
@@ -128,6 +125,7 @@ class Grid extends \Magento\Reports\Block\Adminhtml\Grid\Shopcart
                 'header' => __('Orders'),
                 'align' => 'right',
                 'index' => 'orders',
+                'sortable' => false,
                 'header_css_class' => 'col-qty',
                 'column_css_class' => 'col-qty'
             ]
diff --git a/app/code/Magento/Reports/Model/Resource/Customer/Collection.php b/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
index a4b9fee5599cade00a19481c4a35a4bab335746b..c602eb91ae9b4284b289204770089483d4879ffe 100644
--- a/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
@@ -66,6 +66,11 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
      */
     protected $_quoteItemFactory;
 
+    /**
+     * @var \Magento\Sales\Model\Resource\Order\Collection
+     */
+    protected $orderResource;
+
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
@@ -79,6 +84,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
      * @param \Magento\Framework\Object\Copy\Config $fieldsetConfig
      * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
      * @param \Magento\Quote\Model\Resource\Quote\Item\CollectionFactory $quoteItemFactory
+     * @param \Magento\Sales\Model\Resource\Order\Collection $orderResource
      * @param mixed $connection
      * @param string $modelName
      *
@@ -97,6 +103,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
         \Magento\Framework\Object\Copy\Config $fieldsetConfig,
         \Magento\Quote\Model\QuoteRepository $quoteRepository,
         \Magento\Quote\Model\Resource\Quote\Item\CollectionFactory $quoteItemFactory,
+        \Magento\Sales\Model\Resource\Order\Collection $orderResource,
         $connection = null,
         $modelName = self::CUSTOMER_MODEL_NAME
     ) {
@@ -114,6 +121,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
             $connection,
             $modelName
         );
+        $this->orderResource = $orderResource;
         $this->quoteRepository = $quoteRepository;
         $this->_quoteItemFactory = $quoteItemFactory;
     }
@@ -152,90 +160,6 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
         return $this;
     }
 
-    /**
-     * Order for each customer
-     *
-     * @param string $fromDate
-     * @param string $toDate
-     * @return $this
-     */
-    public function joinOrders($fromDate = '', $toDate = '')
-    {
-        if ($fromDate != '' && $toDate != '') {
-            $dateFilter = " AND orders.created_at BETWEEN '{$fromDate}' AND '{$toDate}'";
-        } else {
-            $dateFilter = '';
-        }
-
-        $this->getSelect()->joinLeft(
-            ['orders' => $this->getTable('sales_order')],
-            "orders.customer_id = e.entity_id" . $dateFilter,
-            []
-        );
-
-        return $this;
-    }
-
-    /**
-     * Add orders count
-     *
-     * @return $this
-     */
-    public function addOrdersCount()
-    {
-        $this->getSelect()->columns(
-            ["orders_count" => "COUNT(orders.entity_id)"]
-        )->where(
-            'orders.state <> ?',
-            \Magento\Sales\Model\Order::STATE_CANCELED
-        )->group(
-            "e.entity_id"
-        );
-
-        return $this;
-    }
-
-    /**
-     * Order summary info for each customer such as orders_count, orders_avg_amount, orders_total_amount
-     *
-     * @param int $storeId
-     * @return $this
-     */
-    public function addSumAvgTotals($storeId = 0)
-    {
-        $adapter = $this->getConnection();
-        $baseSubtotalRefunded = $adapter->getIfNullSql('orders.base_subtotal_refunded', 0);
-        $baseSubtotalCanceled = $adapter->getIfNullSql('orders.base_subtotal_canceled', 0);
-
-        /**
-         * calculate average and total amount
-         */
-        $expr = $storeId ==
-            0 ?
-            "(orders.base_subtotal - {$baseSubtotalCanceled} - {$baseSubtotalRefunded}) * orders.base_to_global_rate" :
-            "orders.base_subtotal - {$baseSubtotalCanceled} - {$baseSubtotalRefunded}";
-
-        $this->getSelect()->columns(
-            ["orders_avg_amount" => "AVG({$expr})"]
-        )->columns(
-            ["orders_sum_amount" => "SUM({$expr})"]
-        );
-
-        return $this;
-    }
-
-    /**
-     * Order by total amount
-     *
-     * @param string $dir
-     * @return $this
-     */
-    public function orderByTotalAmount($dir = self::SORT_ORDER_DESC)
-    {
-        $this->getSelect()->order("orders_sum_amount {$dir}");
-        return $this;
-    }
-
     /**
      * Add order statistics
      *
@@ -259,7 +183,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
         $customerIds = $this->getColumnValues($this->getResource()->getIdFieldName());
 
         if ($this->_addOrderStatistics && !empty($customerIds)) {
-            $adapter = $this->getConnection();
+            $adapter = $this->orderResource->getConnection();
             $baseSubtotalRefunded = $adapter->getIfNullSql('orders.base_subtotal_refunded', 0);
             $baseSubtotalCanceled = $adapter->getIfNullSql('orders.base_subtotal_canceled', 0);
 
@@ -267,9 +191,9 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
                 "(orders.base_subtotal-{$baseSubtotalCanceled}-{$baseSubtotalRefunded})*orders.base_to_global_rate" :
                 "orders.base_subtotal-{$baseSubtotalCanceled}-{$baseSubtotalRefunded}";
 
-            $select = $this->getConnection()->select();
+            $select = $this->orderResource->getConnection()->select();
             $select->from(
-                ['orders' => $this->getTable('sales_order')],
+                ['orders' => $this->orderResource->getTable('sales_order')],
                 [
                     'orders_avg_amount' => "AVG({$totalExpr})",
                     'orders_sum_amount' => "SUM({$totalExpr})",
@@ -286,7 +210,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
                 'orders.customer_id'
             );
 
-            foreach ($this->getConnection()->fetchAll($select) as $ordersInfo) {
+            foreach ($this->orderResource->getConnection()->fetchAll($select) as $ordersInfo) {
                 $this->getItemById($ordersInfo['customer_id'])->addData($ordersInfo);
             }
         }
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Collection.php
index 3e77d75e16eb6f2f451477f1c89ceb4f907b4e8e..3eb9ac629a26e8fdcd075618a98ea3c26357ce1a 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Collection.php
@@ -56,6 +56,11 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     protected $_productType;
 
+    /**
+     * @var \Magento\Quote\Model\Resource\Quote\Collection
+     */
+    protected $quoteResource;
+
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
      * @param \Psr\Log\LoggerInterface $logger
@@ -79,6 +84,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      * @param \Magento\Catalog\Model\Resource\Product $product
      * @param \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory
      * @param \Magento\Catalog\Model\Product\Type $productType
+     * @param \Magento\Quote\Model\Resource\Quote\Collection $quoteResource
      * @param mixed $connection
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -106,6 +112,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
         \Magento\Catalog\Model\Resource\Product $product,
         \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory,
         \Magento\Catalog\Model\Product\Type $productType,
+        \Magento\Quote\Model\Resource\Quote\Collection $quoteResource,
         $connection = null
     ) {
         $this->setProductEntityId($product->getEntityIdField());
@@ -135,6 +142,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
         );
         $this->_eventTypeFactory = $eventTypeFactory;
         $this->_productType = $productType;
+        $this->quoteResource = $quoteResource;
     }
 
     /**
@@ -239,7 +247,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
     public function getSelectCountSql()
     {
         if ($this->_selectCountSqlType == self::SELECT_COUNT_SQL_TYPE_CART) {
-            $countSelect = clone $this->getSelect();
+            $countSelect = clone $this->quoteResource->getSelect();
             $countSelect->reset()->from(
                 ['quote_item_table' => $this->getTable('quote_item')],
                 ['COUNT(DISTINCT quote_item_table.product_id)']
@@ -263,102 +271,6 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
         return $countSelect;
     }
 
-    /**
-     * Add orders count
-     *
-     * @param string $from
-     * @param string $to
-     * @return $this
-     */
-    public function addOrdersCount($from = '', $to = '')
-    {
-        $orderItemTableName = $this->getTable('sales_order_item');
-        $productFieldName = sprintf('e.%s', $this->getProductEntityId());
-
-        $this->getSelect()->joinLeft(
-            ['order_items' => $orderItemTableName],
-            "order_items.product_id = {$productFieldName}",
-            []
-        )->columns(
-            ['orders' => 'COUNT(order_items2.item_id)']
-        )->group(
-            $productFieldName
-        );
-
-        $dateFilter = ['order_items2.item_id = order_items.item_id'];
-        if ($from != '' && $to != '') {
-            $dateFilter[] = $this->_prepareBetweenSql('order_items2.created_at', $from, $to);
-        }
-
-        $this->getSelect()->joinLeft(
-            ['order_items2' => $orderItemTableName],
-            implode(' AND ', $dateFilter),
-            []
-        );
-
-        return $this;
-    }
-
-    /**
-     * Add ordered qty's
-     *
-     * @param string $from
-     * @param string $to
-     * @return $this
-     */
-    public function addOrderedQty($from = '', $to = '')
-    {
-        $adapter = $this->getConnection();
-        $compositeTypeIds = $this->_productType->getCompositeTypes();
-        $orderTableAliasName = $adapter->quoteIdentifier('order');
-
-        $orderJoinCondition = [
-            $orderTableAliasName . '.entity_id = order_items.order_id',
-            $adapter->quoteInto("{$orderTableAliasName}.state <> ?", \Magento\Sales\Model\Order::STATE_CANCELED),
-        ];
-
-        $productJoinCondition = [
-            $adapter->quoteInto('(e.type_id NOT IN (?))', $compositeTypeIds),
-            'e.entity_id = order_items.product_id',
-           $adapter->quoteInto('e.attribute_set_id = ?', $this->getProductAttributeSetId()),
-        ];
-
-        if ($from != '' && $to != '') {
-            $fieldName = $orderTableAliasName . '.created_at';
-            $orderJoinCondition[] = $this->_prepareBetweenSql($fieldName, $from, $to);
-        }
-
-        $this->getSelect()->reset()->from(
-            ['order_items' => $this->getTable('sales_order_item')],
-            ['ordered_qty' => 'SUM(order_items.qty_ordered)', 'order_items_name' => 'order_items.name']
-        )->joinInner(
-            ['order' => $this->getTable('sales_order')],
-            implode(' AND ', $orderJoinCondition),
-            []
-        )->joinLeft(
-            ['e' => $this->getProductEntityTableName()],
-            implode(' AND ', $productJoinCondition),
-            [
-                'entity_id' => 'order_items.product_id',
-                'attribute_set_id' => 'e.attribute_set_id',
-                'type_id' => 'e.type_id',
-                'sku' => 'e.sku',
-                'has_options' => 'e.has_options',
-                'required_options' => 'e.required_options',
-                'created_at' => 'e.created_at',
-                'updated_at' => 'e.updated_at'
-            ]
-        )->where(
-            'parent_item_id IS NULL'
-        )->group(
-            'order_items.product_id'
-        )->having(
-            'SUM(order_items.qty_ordered) > ?',
-            0
-        );
-        return $this;
-    }
-
     /**
      * Set order
      *
@@ -368,7 +280,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function setOrder($attribute, $dir = self::SORT_ORDER_DESC)
     {
-        if (in_array($attribute, ['carts', 'orders', 'ordered_qty'])) {
+        if (in_array($attribute, ['carts'])) {
             $this->getSelect()->order($attribute . ' ' . $dir);
         } else {
             parent::setOrder($attribute, $dir);
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
index 521135eeb0422efb7b7f4b9822d00b567793c81b..0c71c26aa69ebf90ac9456c0d898508470399c55 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
@@ -68,6 +68,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
      * @param \Magento\Catalog\Model\Resource\Product $product
      * @param \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory
      * @param \Magento\Catalog\Model\Product\Type $productType
+     * @param \Magento\Quote\Model\Resource\Quote\Collection $quoteResource
      * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
      * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
      * @param \Magento\CatalogInventory\Model\Resource\Stock\Item $itemResource
@@ -98,6 +99,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
         \Magento\Catalog\Model\Resource\Product $product,
         \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory,
         \Magento\Catalog\Model\Product\Type $productType,
+        \Magento\Quote\Model\Resource\Quote\Collection $quoteResource,
         \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
         \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
         \Magento\CatalogInventory\Model\Resource\Stock\Item $itemResource,
@@ -126,6 +128,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
             $product,
             $eventTypeFactory,
             $productType,
+            $quoteResource,
             $connection
         );
         $this->stockRegistry = $stockRegistry;
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Sold/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Sold/Collection.php
index 0b91b4a360e7134702a1785a73c75be07ae973ba..2959e2cd45165da18c3911b55f876298326e3452 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Sold/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Sold/Collection.php
@@ -11,7 +11,7 @@
  */
 namespace Magento\Reports\Model\Resource\Product\Sold;
 
-class Collection extends \Magento\Reports\Model\Resource\Product\Collection
+class Collection extends \Magento\Reports\Model\Resource\Order\Collection
 {
     /**
      * Set Date range to collection
@@ -34,6 +34,46 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
         return $this;
     }
 
+    /**
+     * Add ordered qty's
+     *
+     * @param string $from
+     * @param string $to
+     * @return $this
+     */
+    public function addOrderedQty($from = '', $to = '')
+    {
+        $adapter = $this->getConnection();
+        $orderTableAliasName = $adapter->quoteIdentifier('order');
+
+        $orderJoinCondition = [
+            $orderTableAliasName . '.entity_id = order_items.order_id',
+            $adapter->quoteInto("{$orderTableAliasName}.state <> ?", \Magento\Sales\Model\Order::STATE_CANCELED),
+        ];
+
+        if ($from != '' && $to != '') {
+            $fieldName = $orderTableAliasName . '.created_at';
+            $orderJoinCondition[] = $this->prepareBetweenSql($fieldName, $from, $to);
+        }
+
+        $this->getSelect()->reset()->from(
+            ['order_items' => $this->getTable('sales_order_item')],
+            ['ordered_qty' => 'SUM(order_items.qty_ordered)', 'order_items_name' => 'order_items.name']
+        )->joinInner(
+            ['order' => $this->getTable('sales_order')],
+            implode(' AND ', $orderJoinCondition),
+            []
+        )->where(
+            'parent_item_id IS NULL'
+        )->group(
+            'order_items.product_id'
+        )->having(
+            'SUM(order_items.qty_ordered) > ?',
+            0
+        );
+        return $this;
+    }
+
     /**
      * Set store filter to collection
      *
@@ -49,29 +89,38 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
     }
 
     /**
-     * Add website product limitation
+     * Set order
      *
+     * @param string $attribute
+     * @param string $dir
      * @return $this
      */
-    protected function _productLimitationJoinWebsite()
+    public function setOrder($attribute, $dir = self::SORT_ORDER_DESC)
     {
-        $filters = $this->_productLimitationFilters;
-        $conditions = ['product_website.product_id=e.entity_id'];
-        if (isset($filters['website_ids'])) {
-            $conditions[] = $this->getConnection()->quoteInto(
-                'product_website.website_id IN(?)',
-                $filters['website_ids']
-            );
-
-            $subQuery = $this->getConnection()->select()->from(
-                ['product_website' => $this->getTable('catalog_product_website')],
-                ['product_website.product_id']
-            )->where(
-                join(' AND ', $conditions)
-            );
-            $this->getSelect()->where('e.entity_id IN( ' . $subQuery . ' )');
+        if (in_array($attribute, ['orders', 'ordered_qty'])) {
+            $this->getSelect()->order($attribute . ' ' . $dir);
+        } else {
+            parent::setOrder($attribute, $dir);
         }
 
         return $this;
     }
+
+    /**
+     * Prepare between sql
+     *
+     * @param string $fieldName Field name with table suffix ('created_at' or 'main_table.created_at')
+     * @param string $from
+     * @param string $to
+     * @return string Formatted sql string
+     */
+    protected function prepareBetweenSql($fieldName, $from, $to)
+    {
+        return sprintf(
+            '(%s BETWEEN %s AND %s)',
+            $fieldName,
+            $this->getConnection()->quote($from),
+            $this->getConnection()->quote($to)
+        );
+    }
 }
diff --git a/app/code/Magento/Reports/Model/Resource/Quote/Collection.php b/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
index 38ba00038520a828469d8d5c1cda8976c9a3b0b3..cb2a9333fe01e3f67cc168067fc0fdc0a1bcc773 100644
--- a/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
@@ -13,6 +13,10 @@
  */
 namespace Magento\Reports\Model\Resource\Quote;
 
+/**
+ * Class Collection
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
 {
     const SELECT_COUNT_SQL_TYPE_CART = 1;
@@ -39,12 +43,17 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
     /**
      * @var \Magento\Catalog\Model\Resource\Product\Collection
      */
-    protected $_productResource;
+    protected $productResource;
 
     /**
      * @var \Magento\Customer\Model\Resource\Customer
      */
-    protected $_customerResource;
+    protected $customerResource;
+
+    /**
+     * @var \Magento\Sales\Model\Resource\Order\Collection
+     */
+    protected $orderResource;
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
@@ -53,6 +62,7 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Catalog\Model\Resource\Product\Collection $productResource
      * @param \Magento\Customer\Model\Resource\Customer $customerResource
+     * @param \Magento\Sales\Model\Resource\Order\Collection $orderResource
      * @param null $connection
      * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
      */
@@ -63,12 +73,14 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Catalog\Model\Resource\Product\Collection $productResource,
         \Magento\Customer\Model\Resource\Customer $customerResource,
+        \Magento\Sales\Model\Resource\Order\Collection $orderResource,
         $connection = null,
         \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
         parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
-        $this->_productResource = $productResource;
-        $this->_customerResource = $customerResource;
+        $this->productResource = $productResource;
+        $this->customerResource = $customerResource;
+        $this->orderResource = $orderResource;
     }
 
     /**
@@ -120,75 +132,47 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
     /**
      * Prepare select query for products in carts report
      *
-     * @return $this
+     * @return \Magento\Framework\DB\Select
      */
-    public function prepareForProductsInCarts()
+    public function prepareActiveCartItems()
     {
-        $productAttrName = $this->_productResource->getAttribute('name');
-        $productAttrNameId = (int)$productAttrName->getAttributeId();
-        $productAttrNameTable = $productAttrName->getBackend()->getTable();
-        $productAttrPrice = $this->_productResource->getAttribute('price');
-        $productAttrPriceId = (int)$productAttrPrice->getAttributeId();
-        $productAttrPriceTable = $productAttrPrice->getBackend()->getTable();
-
-        $this->getSelect()->useStraightJoin(
-            true
-        )->reset(
-            \Zend_Db_Select::COLUMNS
-        )->joinInner(
-            ['quote_items' => $this->getTable('quote_item')],
-            'quote_items.quote_id = main_table.entity_id',
-            null
-        )->joinInner(
-            ['e' => $this->getTable('catalog_product_entity')],
-            'e.entity_id = quote_items.product_id',
-            null
-        )->joinInner(
-            ['product_name' => $productAttrNameTable],
-            'product_name.entity_id = e.entity_id'
-                . ' AND product_name.attribute_id = ' . $productAttrNameId
-                . ' AND product_name.store_id = ' . \Magento\Store\Model\Store::DEFAULT_STORE_ID,
-            ['name' => 'product_name.value']
-        )->joinInner(
-            ['product_price' => $productAttrPriceTable],
-            "product_price.entity_id = e.entity_id AND product_price.attribute_id = {$productAttrPriceId}",
-            ['price' => new \Zend_Db_Expr('product_price.value * main_table.base_to_global_rate')]
-        )->joinLeft(
-            ['order_items' => new \Zend_Db_Expr(sprintf('(%s)', $this->getOrdersSubSelect()))],
-            'order_items.product_id = e.entity_id',
-            []
-        )->columns(
-            'e.*'
-        )->columns(
-            ['carts' => new \Zend_Db_Expr('COUNT(quote_items.item_id)')]
-        )->columns(
-            'order_items.orders'
-        )->where(
-            'main_table.is_active = ?',
-            1
-        )->group(
-            'quote_items.product_id'
-        );
+        $quoteItemsSelect = $this->getSelect();
+        $quoteItemsSelect->reset()
+            ->from(['main_table' => $this->getTable('quote')], '')
+            ->columns('quote_items.product_id')
+            ->columns(['carts' => new \Zend_Db_Expr('COUNT(quote_items.item_id)')])
+            ->columns('main_table.base_to_global_rate')
+            ->joinInner(
+                ['quote_items' => $this->getTable('quote_item')],
+                'quote_items.quote_id = main_table.entity_id',
+                null
+            )->where(
+                'main_table.is_active = ?',
+                1
+            )->group(
+                'quote_items.product_id'
+            );
 
-        return $this;
+        return $quoteItemsSelect;
     }
 
     /**
-     * Orders quantity subselect
+     * Orders quantity data
      *
-     * @return \Magento\Framework\DB\Select
+     * @param array $productIds
+     * @return array
      */
-    protected function getOrdersSubSelect()
+    protected function getOrdersData(array $productIds)
     {
-        $ordersSubSelect = clone $this->getSelect();
+        $ordersSubSelect = clone $this->orderResource->getSelect();
         $ordersSubSelect->reset()->from(
             ['oi' => $this->getTable('sales_order_item')],
-            ['orders' => new \Zend_Db_Expr('COUNT(1)'), 'product_id']
-        )->group(
+            ['product_id', 'orders' => new \Zend_Db_Expr('COUNT(1)')]
+        )->where('oi.product_id IN (?)', $productIds)->group(
             'oi.product_id'
         );
 
-        return $ordersSubSelect;
+        return $this->orderResource->getConnection()->fetchAssoc($ordersSubSelect);
     }
 
     /**
@@ -211,7 +195,7 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
      */
     public function addCustomerData($filter = null)
     {
-        $customersSelect = $this->_customerResource->getReadConnection()->select();
+        $customersSelect = $this->customerResource->getReadConnection()->select();
         $customersSelect->from(['customer' => 'customer_entity'], 'entity_id');
         if (isset($filter['customer_name'])) {
             $customersSelect = $this->getCustomerNames($customersSelect);
@@ -223,7 +207,7 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
         if (isset($filter['email'])) {
             $customersSelect->where('customer.email LIKE ?', '%' . $filter['email'] . '%');
         }
-        $filteredCustomers = $this->_customerResource->getReadConnection()->fetchCol($customersSelect);
+        $filteredCustomers = $this->customerResource->getReadConnection()->fetchCol($customersSelect);
         $this->getSelect()->where('main_table.customer_id IN (?)', $filteredCustomers);
         return $this;
     }
@@ -270,24 +254,14 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
     /**
      * Get select count sql
      *
-     * @return string
+     * @return \Magento\Framework\DB\Select
      */
     public function getSelectCountSql()
     {
-        $countSelect = clone $this->getSelect();
-        $countSelect->reset(\Zend_Db_Select::ORDER);
-        $countSelect->reset(\Zend_Db_Select::LIMIT_COUNT);
-        $countSelect->reset(\Zend_Db_Select::LIMIT_OFFSET);
-        $countSelect->reset(\Zend_Db_Select::COLUMNS);
-        $countSelect->reset(\Zend_Db_Select::GROUP);
-        $countSelect->resetJoinLeft();
-
-        if ($this->_selectCountSqlType == self::SELECT_COUNT_SQL_TYPE_CART) {
-            $countSelect->columns("COUNT(DISTINCT e.entity_id)");
-        } else {
-            $countSelect->columns("COUNT(DISTINCT main_table.entity_id)");
-        }
-
+        $countSelect = clone $this->prepareActiveCartItems();
+        $countSelect->reset(\Zend_Db_Select::COLUMNS)
+            ->reset(\Zend_Db_Select::GROUP)
+            ->columns('COUNT(DISTINCT quote_items.product_id)');
         return $countSelect;
     }
 
@@ -297,10 +271,10 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
      */
     protected function getCustomerNames($select)
     {
-        $attrFirstname = $this->_customerResource->getAttribute('firstname');
+        $attrFirstname = $this->customerResource->getAttribute('firstname');
         $attrFirstnameId = (int)$attrFirstname->getAttributeId();
         $attrFirstnameTableName = $attrFirstname->getBackend()->getTable();
-        $attrLastname = $this->_customerResource->getAttribute('lastname');
+        $attrLastname = $this->customerResource->getAttribute('lastname');
         $attrLastnameId = (int)$attrLastname->getAttributeId();
         $attrLastnameTableName = $attrLastname->getBackend()->getTable();
         $select->joinInner(
@@ -326,7 +300,7 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
      */
     public function resolveCustomerNames()
     {
-        $select = $this->_customerResource->getReadConnection()->select();
+        $select = $this->customerResource->getReadConnection()->select();
         $customerName = $select->getAdapter()->getConcatSql(['cust_fname.value', 'cust_lname.value'], ' ');
 
         $select->from(
@@ -343,4 +317,69 @@ class Collection extends \Magento\Quote\Model\Resource\Quote\Collection
             next($customersData);
         }
     }
+
+    /**
+     * Separate query for product and order data
+     *
+     * @param array $productIds
+     * @return array
+     * @throws \Magento\Eav\Exception
+     */
+    protected function getProductData(array $productIds)
+    {
+        $productConnection = $this->productResource->getConnection('read');
+        $productAttrName = $this->productResource->getAttribute('name');
+        $productAttrNameId = (int)$productAttrName->getAttributeId();
+        $productAttrPrice = $this->productResource->getAttribute('price');
+        $productAttrPriceId = (int)$productAttrPrice->getAttributeId();
+
+        $select = clone $this->productResource->getSelect();
+        $select->reset();
+        $select->from(
+            ['main_table' => $this->getTable('catalog_product_entity')]
+        )->useStraightJoin(
+            true
+        )->joinInner(
+            ['product_name' => $productAttrName->getBackend()->getTable()],
+            'product_name.entity_id = main_table.entity_id'
+            . ' AND product_name.attribute_id = ' . $productAttrNameId
+            . ' AND product_name.store_id = ' . \Magento\Store\Model\Store::DEFAULT_STORE_ID,
+            ['name' => 'product_name.value']
+        )->joinInner(
+            ['product_price' => $productAttrPrice->getBackend()->getTable()],
+            "product_price.entity_id = main_table.entity_id AND product_price.attribute_id = {$productAttrPriceId}",
+            ['price' => new \Zend_Db_Expr('product_price.value')]
+        )->where('main_table.entity_id IN (?)', $productIds);
+
+        $productData = $productConnection->fetchAssoc($select);
+        return $productData;
+    }
+
+    /**
+     * Add data fetched from another database
+     *
+     * @return $this
+     */
+    protected function _afterLoad()
+    {
+        parent::_afterLoad();
+        $items = $this->getItems();
+        $productIds = [];
+        foreach ($items as $item) {
+            $productIds[] = $item->getProductId();
+        }
+        $productData = $this->getProductData($productIds);
+        $orderData = $this->getOrdersData($productIds);
+        foreach ($items as $item) {
+            $item->setId($item->getProductId());
+            $item->setPrice($productData[$item->getProductId()]['price'] * $item->getBaseToGlobalRate());
+            $item->setName($productData[$item->getProductId()]['name']);
+            $item->setOrders(0);
+            if (isset($orderData[$item->getProductId()])) {
+                $item->setOrders($orderData[$item->getProductId()]['orders']);
+            }
+        }
+
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Reports/Setup/InstallSchema.php b/app/code/Magento/Reports/Setup/InstallSchema.php
index bea0fc3cb2e6710e0d27b9f47aabe6bbb34d2c52..707597f5a747a2192ff1cb20072745c0a6e21ff4 100644
--- a/app/code/Magento/Reports/Setup/InstallSchema.php
+++ b/app/code/Magento/Reports/Setup/InstallSchema.php
@@ -111,7 +111,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_id',
                 $installer->getTable('customer_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -124,7 +123,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -132,8 +130,7 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Reports Compared Product Index Table');
         $installer->getConnection()->createTable($table);
@@ -222,7 +219,6 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_id',
                 $installer->getTable('customer_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -235,7 +231,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -243,8 +238,7 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Reports Viewed Product Index Table');
         $installer->getConnection()->createTable($table);
@@ -357,7 +351,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -365,7 +358,6 @@ class InstallSchema implements InstallSchemaInterface
                 'event_type_id',
                 $installer->getTable('report_event_types'),
                 'event_type_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Reports Event Table');
@@ -452,7 +444,6 @@ class InstallSchema implements InstallSchemaInterface
                     'customer_id',
                     $installer->getTable('customer_entity'),
                     'entity_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
                 )
                 ->addForeignKey(
@@ -465,7 +456,6 @@ class InstallSchema implements InstallSchemaInterface
                     'product_id',
                     $installer->getTable('catalog_product_entity'),
                     'entity_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
                 )
                 ->addForeignKey(
@@ -473,8 +463,7 @@ class InstallSchema implements InstallSchemaInterface
                     'store_id',
                     $installer->getTable('store'),
                     'store_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                    \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
                 )
                 ->setComment('Reports Compared Product Index Table');
             $installer->getConnection()->createTable($table);
@@ -556,7 +545,6 @@ class InstallSchema implements InstallSchemaInterface
                     'customer_id',
                     $installer->getTable('customer_entity'),
                     'entity_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
                 )
                 ->addForeignKey(
@@ -569,7 +557,6 @@ class InstallSchema implements InstallSchemaInterface
                     'product_id',
                     $installer->getTable('catalog_product_entity'),
                     'entity_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                     \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
                 )
                 ->addForeignKey(
@@ -577,8 +564,7 @@ class InstallSchema implements InstallSchemaInterface
                     'store_id',
                     $installer->getTable('store'),
                     'store_id',
-                    \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                    \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
                 )
                 ->setComment('Reports Viewed Product Index Table');
             $installer->getConnection()->createTable($table);
@@ -667,7 +653,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -680,7 +665,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Most Viewed Products Aggregated Daily');
@@ -769,7 +753,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -782,7 +765,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Most Viewed Products Aggregated Monthly');
@@ -871,7 +853,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -884,7 +865,6 @@ class InstallSchema implements InstallSchemaInterface
                 'product_id',
                 $installer->getTable('catalog_product_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Most Viewed Products Aggregated Yearly');
diff --git a/app/code/Magento/Reports/Test/Unit/Model/Resource/Report/Quote/CollectionTest.php b/app/code/Magento/Reports/Test/Unit/Model/Resource/Report/Quote/CollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3b7eadd6da68560e28bcad5b9a1b5249209c615
--- /dev/null
+++ b/app/code/Magento/Reports/Test/Unit/Model/Resource/Report/Quote/CollectionTest.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Reports\Test\Unit\Model\Resource\Report\Quote;
+
+use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use \Magento\Reports\Model\Resource\Quote\Collection as Collection;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $selectMock;
+
+    protected function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+        $this->selectMock = $this->getMock('\Magento\Framework\DB\Select', [], [], '', false);
+    }
+
+    public function testGetSelectCountSql()
+    {
+        /** @var $collection \PHPUnit_Framework_MockObject_MockObject */
+        $constructArgs = $this->objectManager
+            ->getConstructArguments('Magento\Reports\Model\Resource\Quote\Collection');
+        $collection = $this->getMock(
+            'Magento\Reports\Model\Resource\Quote\Collection',
+            ['prepareActiveCartItems', 'getSelect'],
+            $constructArgs,
+            '',
+            false
+        );
+
+        $collection->expects($this->once())->method('prepareActiveCartItems')->willReturn($this->selectMock);
+        $this->selectMock->expects($this->atLeastOnce())->method('reset')->willReturnSelf();
+        $this->selectMock->expects($this->once())
+            ->method('columns')
+            ->with('COUNT(DISTINCT quote_items.product_id)')
+            ->willReturnSelf();
+        $this->assertEquals($this->selectMock, $collection->getSelectCountSql());
+    }
+
+    public function testPrepareActiveCartItems()
+    {
+        /** @var $collection \PHPUnit_Framework_MockObject_MockObject */
+        $constructArgs = $this->objectManager
+            ->getConstructArguments('Magento\Reports\Model\Resource\Quote\Collection');
+        $collection = $this->getMock(
+            'Magento\Reports\Model\Resource\Quote\Collection',
+            ['getSelect', 'getTable'],
+            $constructArgs,
+            '',
+            false
+        );
+
+        $collection->expects($this->once())->method('getSelect')->willReturn($this->selectMock);
+        $this->selectMock->expects($this->once())->method('reset')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('from')->willReturnSelf();
+        $this->selectMock->expects($this->atLeastOnce())->method('columns')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('joinInner')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('where')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('group')->willReturnSelf();
+        $collection->expects($this->exactly(2))->method('getTable')->willReturn('table');
+        $collection->prepareActiveCartItems();
+    }
+
+    public function testLoadWithFilter()
+    {
+        /** @var $collection \PHPUnit_Framework_MockObject_MockObject */
+        $constructArgs = $this->objectManager
+            ->getConstructArguments('Magento\Reports\Model\Resource\Quote\Collection');
+        $constructArgs['eventManager'] = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
+        $readConnectionMock = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface', [], [], '', false);
+        $resourceMock = $this->getMock('\Magento\Quote\Model\Resource\Quote', [], [], '', false);
+        $constructArgs['resource'] = $resourceMock;
+        $productResourceMock = $this->getMock('\Magento\Catalog\Model\Resource\Product\Collection', [], [], '', false);
+        $constructArgs['productResource'] = $productResourceMock;
+        $orderResourceMock = $this->getMock('\Magento\Sales\Model\Resource\Order\Collection', [], [], '', false);
+        $constructArgs['orderResource'] = $orderResourceMock;
+
+        $collection = $this->getMock(
+            'Magento\Reports\Model\Resource\Quote\Collection',
+            [
+                '_beforeLoad',
+                '_renderFilters',
+                '_renderOrders',
+                '_renderLimit',
+                'printLogQuery',
+                'getData',
+                '_setIsLoaded',
+                'setConnection',
+                '_initSelect',
+                'getTable',
+                'getItems',
+                'getOrdersData',
+            ],
+            $constructArgs
+        );
+        //load()
+        $collection->expects($this->once())->method('_beforeLoad')->willReturnSelf();
+        $collection->expects($this->once())->method('_renderFilters')->willReturnSelf();
+        $collection->expects($this->once())->method('_renderOrders')->willReturnSelf();
+        $collection->expects($this->once())->method('_renderLimit')->willReturnSelf();
+        $collection->expects($this->once())->method('printLogQuery')->willReturnSelf();
+        $collection->expects($this->once())->method('getData')->willReturn(null);
+        $collection->expects($this->once())->method('_setIsLoaded')->willReturnSelf();
+
+        //productLoad()
+        $productAttributeMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
+            [],
+            [],
+            '',
+            false
+        );
+        $priceAttributeMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
+            [],
+            [],
+            '',
+            false
+        );
+        $productResourceMock->expects($this->once())
+            ->method('getConnection')
+            ->with('read')
+            ->willReturn($readConnectionMock);
+        $productResourceMock->expects($this->any())
+            ->method('getAttribute')
+            ->willReturnMap([['name', $productAttributeMock], ['price', $priceAttributeMock]]);
+        $productResourceMock->expects($this->once())->method('getSelect')->willReturn($this->selectMock);
+        $this->selectMock->expects($this->once())->method('reset')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('from')->willReturnSelf();
+        $this->selectMock->expects($this->once())->method('useStraightJoin')->willReturnSelf();
+        $this->selectMock->expects($this->exactly(2))->method('joinInner')->willReturnSelf();
+        $collection->expects($this->once())->method('getOrdersData')->willReturn([]);
+
+        $productAttributeMock->expects($this->once())->method('getBackend')->willReturnSelf();
+        $priceAttributeMock->expects($this->once())->method('getBackend')->willReturnSelf();
+        $readConnectionMock->expects($this->once())->method('fetchAssoc')->willReturn([1, 2, 3]);
+
+        //_afterLoad()
+        $collection->expects($this->once())->method('getItems')->willReturn([]);
+
+        $collection->loadWithFilter();
+    }
+}
diff --git a/app/code/Magento/Review/Setup/InstallSchema.php b/app/code/Magento/Review/Setup/InstallSchema.php
index 6d5a14fe2880f21d46abd7d3be56f5be04d60fb0..276b7389bff8fd84a89d735d65747ae079a59320 100644
--- a/app/code/Magento/Review/Setup/InstallSchema.php
+++ b/app/code/Magento/Review/Setup/InstallSchema.php
@@ -125,7 +125,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('review_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -133,7 +132,6 @@ class InstallSchema implements InstallSchemaInterface
                 'status_id',
                 $installer->getTable('review_status'),
                 'status_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION,
                 \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
             )
             ->setComment('Review base information');
@@ -210,15 +208,13 @@ class InstallSchema implements InstallSchemaInterface
                 'customer_id',
                 $installer->getTable('customer_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->addForeignKey(
                 $installer->getFkName('review_detail', 'review_id', 'review', 'review_id'),
                 'review_id',
                 $installer->getTable('review'),
                 'review_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -226,8 +222,7 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+                \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
             )
             ->setComment('Review detail information');
         $installer->getConnection()->createTable($table);
@@ -288,7 +283,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Review aggregates');
@@ -322,7 +316,6 @@ class InstallSchema implements InstallSchemaInterface
                 'review_id',
                 $installer->getTable('review'),
                 'review_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -330,7 +323,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Review Store');
@@ -425,7 +417,6 @@ class InstallSchema implements InstallSchemaInterface
                 'entity_id',
                 $installer->getTable('rating_entity'),
                 'entity_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Ratings');
@@ -480,7 +471,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rating_id',
                 $installer->getTable('rating'),
                 'rating_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Rating options');
@@ -570,7 +560,6 @@ class InstallSchema implements InstallSchemaInterface
                 'option_id',
                 $installer->getTable('rating_option'),
                 'option_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -578,7 +567,6 @@ class InstallSchema implements InstallSchemaInterface
                 'review_id',
                 $installer->getTable('review'),
                 'review_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Rating option values');
@@ -658,7 +646,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rating_id',
                 $installer->getTable('rating'),
                 'rating_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -666,7 +653,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Rating vote aggregated');
@@ -700,7 +686,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -708,8 +693,7 @@ class InstallSchema implements InstallSchemaInterface
                 'rating_id',
                 $installer->getTable('rating'),
                 'rating_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-                \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Rating Store');
         $installer->getConnection()->createTable($table);
@@ -749,7 +733,6 @@ class InstallSchema implements InstallSchemaInterface
                 'rating_id',
                 $installer->getTable('rating'),
                 'rating_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->addForeignKey(
@@ -757,7 +740,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Rating Title');
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php
index 63b1f9055bdd1e78a525a655e5cef4e96595048d..832aed45797e962b32264d1681ca979fee5cfe8c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php
@@ -6,7 +6,7 @@
 namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
 
 use Magento\Backend\App\Action;
-use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
+use Magento\Sales\Model\Order\Email\Sender\CreditmemoCommentSender;
 
 class AddComment extends \Magento\Backend\App\Action
 {
@@ -16,9 +16,9 @@ class AddComment extends \Magento\Backend\App\Action
     protected $creditmemoLoader;
 
     /**
-     * @var CreditmemoSender
+     * @var CreditmemoCommentSender
      */
-    protected $creditmemoSender;
+    protected $creditmemoCommentSender;
 
     /**
      * @var \Magento\Framework\View\Result\PageFactory
@@ -38,7 +38,7 @@ class AddComment extends \Magento\Backend\App\Action
     /**
      * @param Action\Context $context
      * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
-     * @param CreditmemoSender $creditmemoSender
+     * @param CreditmemoCommentSender $creditmemoCommentSender
      * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
      * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
      * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
@@ -46,13 +46,13 @@ class AddComment extends \Magento\Backend\App\Action
     public function __construct(
         Action\Context $context,
         \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader,
-        CreditmemoSender $creditmemoSender,
+        CreditmemoCommentSender $creditmemoCommentSender,
         \Magento\Framework\View\Result\PageFactory $resultPageFactory,
         \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
         \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
     ) {
         $this->creditmemoLoader = $creditmemoLoader;
-        $this->creditmemoSender = $creditmemoSender;
+        $this->creditmemoCommentSender = $creditmemoCommentSender;
         $this->resultPageFactory = $resultPageFactory;
         $this->resultJsonFactory = $resultJsonFactory;
         $this->resultRawFactory = $resultRawFactory;
@@ -94,7 +94,7 @@ class AddComment extends \Magento\Backend\App\Action
             );
             $comment->save();
 
-            $this->creditmemoSender->send($creditmemo, !empty($data['is_customer_notified']), $data['comment']);
+            $this->creditmemoCommentSender->send($creditmemo, !empty($data['is_customer_notified']), $data['comment']);
             $resultPage = $this->resultPageFactory->create();
             $response = $resultPage->getLayout()->getBlock('creditmemo_comments')->toHtml();
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
index 6ba3acd497b1f06992c9b871cc1cc63f2a1da6de..dbbd9dd55e33e64ae70286cadd0111f9a54d363b 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -81,16 +81,15 @@ class Save extends \Magento\Backend\App\Action
                     );
                 }
 
-                $comment = '';
                 if (!empty($data['comment_text'])) {
                     $creditmemo->addComment(
                         $data['comment_text'],
                         isset($data['comment_customer_notify']),
                         isset($data['is_visible_on_front'])
                     );
-                    if (isset($data['comment_customer_notify'])) {
-                        $comment = $data['comment_text'];
-                    }
+
+                    $creditmemo->setCustomerNote($data['comment_text']);
+                    $creditmemo->setCustomerNoteNotify(isset($data['comment_customer_notify']));
                 }
 
                 if (isset($data['do_refund'])) {
@@ -107,9 +106,6 @@ class Save extends \Magento\Backend\App\Action
                 }
 
                 $creditmemo->register();
-                if (!empty($data['send_email'])) {
-                    $creditmemo->setEmailSent(true);
-                }
 
                 $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
                 $transactionSave = $this->_objectManager->create(
@@ -123,7 +119,10 @@ class Save extends \Magento\Backend\App\Action
                     $transactionSave->addObject($creditmemo->getInvoice());
                 }
                 $transactionSave->save();
-                $this->creditmemoSender->send($creditmemo, !empty($data['send_email']), $comment);
+
+                if (!empty($data['send_email'])) {
+                    $this->creditmemoSender->send($creditmemo);
+                }
 
                 $this->messageManager->addSuccess(__('You created the credit memo.'));
                 $this->_getSession()->getCommentText(true);
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
index 1fffaf8a03ee16324a611fdf6f1b9f862c1367af..3758ad060f0dcb4c6714cac12fa1ad9d41b7540e 100755
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
@@ -9,7 +9,7 @@ namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
 use Magento\Backend\App\Action;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Registry;
-use Magento\Sales\Model\Order\Email\Sender\InvoiceCommentSender;
+use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
 use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
 use Magento\Sales\Model\Order\Invoice;
 
@@ -19,9 +19,9 @@ use Magento\Sales\Model\Order\Invoice;
 class Save extends \Magento\Backend\App\Action
 {
     /**
-     * @var InvoiceCommentSender
+     * @var InvoiceSender
      */
-    protected $invoiceCommentSender;
+    protected $invoiceSender;
 
     /**
      * @var ShipmentSender
@@ -36,17 +36,17 @@ class Save extends \Magento\Backend\App\Action
     /**
      * @param Action\Context $context
      * @param Registry $registry
-     * @param InvoiceCommentSender $invoiceCommentSender
+     * @param InvoiceSender $invoiceSender
      * @param ShipmentSender $shipmentSender
      */
     public function __construct(
         Action\Context $context,
         Registry $registry,
-        InvoiceCommentSender $invoiceCommentSender,
+        InvoiceSender $invoiceSender,
         ShipmentSender $shipmentSender
     ) {
         $this->registry = $registry;
-        $this->invoiceCommentSender = $invoiceCommentSender;
+        $this->invoiceSender = $invoiceSender;
         $this->shipmentSender = $shipmentSender;
         parent::__construct($context);
     }
@@ -153,14 +153,13 @@ class Save extends \Magento\Backend\App\Action
                     isset($data['comment_customer_notify']),
                     isset($data['is_visible_on_front'])
                 );
+
+                $invoice->setCustomerNote($data['comment_text']);
+                $invoice->setCustomerNoteNotify(isset($data['comment_customer_notify']));
             }
 
             $invoice->register();
 
-            if (!empty($data['send_email'])) {
-                $invoice->setEmailSent(true);
-            }
-
             $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
             $invoice->getOrder()->setIsInProcess(true);
 
@@ -175,7 +174,6 @@ class Save extends \Magento\Backend\App\Action
             if (!empty($data['do_shipment']) || (int)$invoice->getOrder()->getForcedShipmentWithInvoice()) {
                 $shipment = $this->_prepareShipment($invoice);
                 if ($shipment) {
-                    $shipment->setEmailSent($invoice->getEmailSent());
                     $transactionSave->addObject($shipment);
                 }
             }
@@ -195,19 +193,19 @@ class Save extends \Magento\Backend\App\Action
             }
 
             // send invoice/shipment emails
-            $comment = '';
-            if (isset($data['comment_customer_notify'])) {
-                $comment = $data['comment_text'];
-            }
             try {
-                $this->invoiceCommentSender->send($invoice, !empty($data['send_email']), $comment);
+                if (!empty($data['send_email'])) {
+                    $this->invoiceSender->send($invoice);
+                }
             } catch (\Exception $e) {
                 $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('We can\'t send the invoice email.'));
             }
             if ($shipment) {
                 try {
-                    $this->shipmentSender->send($shipment, !empty($data['send_email']));
+                    if (!empty($data['send_email'])) {
+                        $this->shipmentSender->send($shipment);
+                    }
                 } catch (\Exception $e) {
                     $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                     $this->messageManager->addError(__('We can\'t send the shipment.'));
diff --git a/app/code/Magento/Sales/Model/Config/Backend/Email/AsyncSending.php b/app/code/Magento/Sales/Model/Config/Backend/Email/AsyncSending.php
new file mode 100644
index 0000000000000000000000000000000000000000..b872e5b9de289a11573bdae418dd86fe57d7abf3
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Config/Backend/Email/AsyncSending.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Config\Backend\Email;
+
+/**
+ * Backend model for global configuration value
+ * 'sales_email/general/async_sending'.
+ */
+class AsyncSending extends \Magento\Framework\App\Config\Value
+{
+    /**
+     * Dispatches corresponding event after saving of configuration
+     * value if it was changed.
+     *
+     * Dispatches next events:
+     *
+     * - config_data_sales_email_general_async_sending_enabled
+     * - config_data_sales_email_general_async_sending_disabled
+     *
+     * @return $this
+     */
+    public function afterSave()
+    {
+        if ($this->isValueChanged()) {
+            $state = $this->getValue() ? 'enabled' : 'disabled';
+
+            $this->_eventManager->dispatch(
+                $this->_eventPrefix . '_sales_email_general_async_sending_' . $state,
+                $this->_getEventData()
+            );
+        }
+
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Observer/SendEmails.php b/app/code/Magento/Sales/Model/Observer/SendEmails.php
new file mode 100644
index 0000000000000000000000000000000000000000..b8c8d00cddb52d4f23c7b51aab51d46776d2d27e
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Observer/SendEmails.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Observer;
+
+/**
+ * Sales emails sending observer.
+ *
+ * Performs handling of cron jobs related to sending emails to customers
+ * after creation/modification of Order, Invoice, Shipment or Creditmemo.
+ */
+class SendEmails
+{
+    /**
+     * Email sender model.
+     *
+     * @var \Magento\Sales\Model\Order\Email\Sender
+     */
+    protected $emailSender;
+
+    /**
+     * Entity resource model.
+     *
+     * @var \Magento\Sales\Model\Resource\EntityAbstract
+     */
+    protected $entityResource;
+
+    /**
+     * Entity collection model.
+     *
+     * @var \Magento\Sales\Model\Resource\Collection\AbstractCollection
+     */
+    protected $entityCollection;
+
+    /**
+     * Global configuration storage.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $globalConfig;
+
+    /**
+     * @param \Magento\Sales\Model\Order\Email\Sender $emailSender
+     * @param \Magento\Sales\Model\Resource\EntityAbstract $entityResource
+     * @param \Magento\Sales\Model\Resource\Collection\AbstractCollection $entityCollection
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
+     */
+    public function __construct(
+        \Magento\Sales\Model\Order\Email\Sender $emailSender,
+        \Magento\Sales\Model\Resource\EntityAbstract $entityResource,
+        \Magento\Sales\Model\Resource\Collection\AbstractCollection $entityCollection,
+        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
+    ) {
+        $this->emailSender = $emailSender;
+        $this->entityResource = $entityResource;
+        $this->entityCollection = $entityCollection;
+        $this->globalConfig = $globalConfig;
+    }
+
+    /**
+     * Handles asynchronous email sending during corresponding
+     * cron job.
+     *
+     * Also method is used in the next events:
+     *
+     * - config_data_sales_email_general_async_sending_disabled
+     *
+     * Works only if asynchronous email sending is enabled
+     * in global settings.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->globalConfig->getValue('sales_email/general/async_sending')) {
+            $this->entityCollection->addFieldToFilter('send_email', ['eq' => 1]);
+            $this->entityCollection->addFieldToFilter('email_sent', ['null' => true]);
+
+            /** @var \Magento\Sales\Model\AbstractModel $item */
+            foreach ($this->entityCollection->getItems() as $item) {
+                if ($this->emailSender->send($item, true)) {
+                    $this->entityResource->save(
+                        $item->setEmailSent(true)
+                    );
+                }
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 667678cc71d24a24127cd0abb7ace46d519d8ba2..94847e91dbe200c9ea34764d4981d08ac986db98 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -45,6 +45,7 @@ use Magento\Sales\Model\Resource\Order\Status\History\Collection as HistoryColle
  * @method bool hasForcedCanCreditmemo()
  * @method bool getIsInProcess()
  * @method \Magento\Customer\Model\Customer getCustomer()
+ * @method \Magento\Sales\Model\Order setSendEmail(bool $value)
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
@@ -520,7 +521,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
      */
     protected function _canVoidOrder()
     {
-        return !($this->canUnhold() || $this->isPaymentReview());
+        return !($this->isCanceled() || $this->canUnhold() || $this->isPaymentReview());
     }
 
     /**
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php
index ec5829dc30e18066c186db6fead57c9a48f4279c..9e77f5afd8635e1b6421a1915684a4c0a858cbd0 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php
@@ -21,6 +21,11 @@ use Magento\Sales\Model\EntityInterface;
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Creditmemo getResource()
  * @method \Magento\Sales\Model\Order\Creditmemo setCreatedAt(string $value)
+ * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
+ * @method string getCustomerNote()
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNoteNotify(bool $value)
+ * @method bool getCustomerNoteNotify()
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
index 50441777e01cab6309354625c12b893d68099517..e476e5ec8b544272154e907ce04cf46be2dd08ba 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php
@@ -10,7 +10,7 @@ use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Creditmemo;
 use Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity;
 use Magento\Sales\Model\Order\Email\Container\Template;
-use Magento\Sales\Model\Order\Email\NotifySender;
+use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Resource\Order\Creditmemo as CreditmemoResource;
 use Magento\Sales\Model\Order\Address\Renderer;
 
@@ -19,7 +19,7 @@ use Magento\Sales\Model\Order\Address\Renderer;
  *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class CreditmemoSender extends NotifySender
+class CreditmemoSender extends Sender
 {
     /**
      * @var PaymentHelper
@@ -32,14 +32,16 @@ class CreditmemoSender extends NotifySender
     protected $creditmemoResource;
 
     /**
-     * @var Renderer
+     * Global configuration storage.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
      */
-    protected $addressRenderer;
+    protected $globalConfig;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var Renderer
      */
-    protected $loggerMock;
+    protected $addressRenderer;
 
     /**
      * @param Template $templateContainer
@@ -48,6 +50,7 @@ class CreditmemoSender extends NotifySender
      * @param \Psr\Log\LoggerInterface $logger
      * @param PaymentHelper $paymentHelper
      * @param CreditmemoResource $creditmemoResource
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
      */
     public function __construct(
@@ -57,50 +60,71 @@ class CreditmemoSender extends NotifySender
         \Psr\Log\LoggerInterface $logger,
         PaymentHelper $paymentHelper,
         CreditmemoResource $creditmemoResource,
+        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
         Renderer $addressRenderer
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->creditmemoResource = $creditmemoResource;
+        $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
     }
 
     /**
-     * Send email to customer
+     * Sends order creditmemo email to the customer.
+     *
+     * Email will be sent immediately in two cases:
+     *
+     * - if asynchronous email sending is disabled in global settings
+     * - if $forceSyncMode parameter is set to TRUE
+     *
+     * Otherwise, email will be sent later during running of
+     * corresponding cron job.
      *
      * @param Creditmemo $creditmemo
-     * @param bool $notify
-     * @param string $comment
+     * @param bool $forceSyncMode
      * @return bool
      */
-    public function send(Creditmemo $creditmemo, $notify = true, $comment = '')
+    public function send(Creditmemo $creditmemo, $forceSyncMode = false)
     {
-        $order = $creditmemo->getOrder();
-        if ($order->getShippingAddress()) {
-            $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
-        } else {
-            $formattedShippingAddress = '';
-        }
-        $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $creditmemo->getOrder(),
-                'creditmemo' => $creditmemo,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'payment_html' => $this->getPaymentHtml($order),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
-            ]
-        );
+        $creditmemo->setSendEmail(true);
+
+        if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
+            $order = $creditmemo->getOrder();
+
+            if ($order->getShippingAddress()) {
+                $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
+            } else {
+                $formattedShippingAddress = '';
+            }
+
+            $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
+
+            $this->templateContainer->setTemplateVars(
+                [
+                    'order' => $order,
+                    'creditmemo' => $creditmemo,
+                    'comment' => $creditmemo->getCustomerNoteNotify() ? $creditmemo->getCustomerNote() : '',
+                    'billing' => $order->getBillingAddress(),
+                    'payment_html' => $this->getPaymentHtml($order),
+                    'store' => $order->getStore(),
+                    'formattedShippingAddress' => $formattedShippingAddress,
+                    'formattedBillingAddress' => $formattedBillingAddress,
+                ]
+            );
 
-        $result = $this->checkAndSend($order, $notify);
-        if ($result) {
-            $creditmemo->setEmailSent(true);
-            $this->creditmemoResource->saveAttribute($creditmemo, 'email_sent');
+            if ($this->checkAndSend($order)) {
+                $creditmemo->setEmailSent(true);
+
+                $this->creditmemoResource->saveAttribute($creditmemo, ['send_email', 'email_sent']);
+
+                return true;
+            }
         }
-        return $result;
+
+        $this->creditmemoResource->saveAttribute($creditmemo, 'send_email');
+
+        return false;
     }
 
     /**
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
index b26d038222bd8d66bfec6e23906e753ef786f59d..0796ff0443b198be2f4f2533e825fb8eca25c2f9 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
@@ -9,15 +9,17 @@ use Magento\Payment\Helper\Data as PaymentHelper;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Email\Container\InvoiceIdentity;
 use Magento\Sales\Model\Order\Email\Container\Template;
-use Magento\Sales\Model\Order\Email\NotifySender;
+use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Order\Invoice;
 use Magento\Sales\Model\Resource\Order\Invoice as InvoiceResource;
 use Magento\Sales\Model\Order\Address\Renderer;
 
 /**
  * Class InvoiceSender
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class InvoiceSender extends NotifySender
+class InvoiceSender extends Sender
 {
     /**
      * @var PaymentHelper
@@ -29,6 +31,13 @@ class InvoiceSender extends NotifySender
      */
     protected $invoiceResource;
 
+    /**
+     * Global configuration storage.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $globalConfig;
+
     /**
      * @var Renderer
      */
@@ -41,6 +50,7 @@ class InvoiceSender extends NotifySender
      * @param \Psr\Log\LoggerInterface $logger
      * @param PaymentHelper $paymentHelper
      * @param InvoiceResource $invoiceResource
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
      */
     public function __construct(
@@ -50,49 +60,70 @@ class InvoiceSender extends NotifySender
         \Psr\Log\LoggerInterface $logger,
         PaymentHelper $paymentHelper,
         InvoiceResource $invoiceResource,
+        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
         Renderer $addressRenderer
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->invoiceResource = $invoiceResource;
+        $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
     }
 
     /**
-     * Send email to customer
+     * Sends order invoice email to the customer.
+     *
+     * Email will be sent immediately in two cases:
+     *
+     * - if asynchronous email sending is disabled in global settings
+     * - if $forceSyncMode parameter is set to TRUE
+     *
+     * Otherwise, email will be sent later during running of
+     * corresponding cron job.
      *
      * @param Invoice $invoice
-     * @param bool $notify
-     * @param string $comment
+     * @param bool $forceSyncMode
      * @return bool
      */
-    public function send(Invoice $invoice, $notify = true, $comment = '')
+    public function send(Invoice $invoice, $forceSyncMode = false)
     {
-        $order = $invoice->getOrder();
-        if ($order->getShippingAddress()) {
-            $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
-        } else {
-            $formattedShippingAddress = '';
-        }
-        $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'invoice' => $invoice,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'payment_html' => $this->getPaymentHtml($order),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
-            ]
-        );
-        $result = $this->checkAndSend($order, $notify);
-        if ($result) {
-            $invoice->setEmailSent(true);
-            $this->invoiceResource->saveAttribute($invoice, 'email_sent');
+        $invoice->setSendEmail(true);
+
+        if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
+            $order = $invoice->getOrder();
+
+            if ($order->getShippingAddress()) {
+                $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
+            } else {
+                $formattedShippingAddress = '';
+            }
+            $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
+            
+            $this->templateContainer->setTemplateVars(
+                [
+                    'order' => $order,
+                    'invoice' => $invoice,
+                    'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '',
+                    'billing' => $order->getBillingAddress(),
+                    'payment_html' => $this->getPaymentHtml($order),
+                    'store' => $order->getStore(),
+                    'formattedShippingAddress' => $formattedShippingAddress,
+                    'formattedBillingAddress' => $formattedBillingAddress
+                ]
+            );
+
+            if ($this->checkAndSend($order)) {
+                $invoice->setEmailSent(true);
+
+                $this->invoiceResource->saveAttribute($invoice, ['send_email', 'email_sent']);
+
+                return true;
+            }
         }
-        return $result;
+
+        $this->invoiceResource->saveAttribute($invoice, 'send_email');
+
+        return false;
     }
 
     /**
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
index 9388270c7db300ea4f4de64b95eca3fa9ada02df..dc2d544d335bd35b9aa5c81327f272bb2c927872 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
@@ -28,6 +28,13 @@ class OrderSender extends Sender
      */
     protected $orderResource;
 
+    /**
+     * Global configuration storage.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $globalConfig;
+
     /**
      * @var Renderer
      */
@@ -40,6 +47,7 @@ class OrderSender extends Sender
      * @param \Psr\Log\LoggerInterface $logger
      * @param PaymentHelper $paymentHelper
      * @param OrderResource $orderResource
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
      */
     public function __construct(
@@ -49,28 +57,48 @@ class OrderSender extends Sender
         \Psr\Log\LoggerInterface $logger,
         PaymentHelper $paymentHelper,
         OrderResource $orderResource,
+        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
         Renderer $addressRenderer
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->orderResource = $orderResource;
+        $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
     }
 
     /**
-     * Send email to customer
+     * Sends order email to the customer.
+     *
+     * Email will be sent immediately in two cases:
+     *
+     * - if asynchronous email sending is disabled in global settings
+     * - if $forceSyncMode parameter is set to TRUE
+     *
+     * Otherwise, email will be sent later during running of
+     * corresponding cron job.
      *
      * @param Order $order
+     * @param bool $forceSyncMode
      * @return bool
      */
-    public function send(Order $order)
+    public function send(Order $order, $forceSyncMode = false)
     {
-        $result = $this->checkAndSend($order);
-        if ($result) {
-            $order->setEmailSent(true);
-            $this->orderResource->saveAttribute($order, 'email_sent');
+        $order->setSendEmail(true);
+
+        if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
+            if ($this->checkAndSend($order)) {
+                $order->setEmailSent(true);
+
+                $this->orderResource->saveAttribute($order, ['send_email', 'email_sent']);
+
+                return true;
+            }
         }
-        return $result;
+
+        $this->orderResource->saveAttribute($order, 'send_email');
+
+        return false;
     }
 
     /**
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
index 811f89496835862b32ef5300de1b844e67182e39..cedd82ae34d6426ed8fff4d60ff9a48565b8ca20 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php
@@ -9,15 +9,17 @@ use Magento\Payment\Helper\Data as PaymentHelper;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Email\Container\ShipmentIdentity;
 use Magento\Sales\Model\Order\Email\Container\Template;
-use Magento\Sales\Model\Order\Email\NotifySender;
+use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Order\Shipment;
 use Magento\Sales\Model\Resource\Order\Shipment as ShipmentResource;
 use Magento\Sales\Model\Order\Address\Renderer;
 
 /**
  * Class ShipmentSender
+ * 
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class ShipmentSender extends NotifySender
+class ShipmentSender extends Sender
 {
     /**
      * @var PaymentHelper
@@ -29,6 +31,13 @@ class ShipmentSender extends NotifySender
      */
     protected $shipmentResource;
 
+    /**
+     * Global configuration storage.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $globalConfig;
+
     /**
      * @var Renderer
      */
@@ -41,6 +50,7 @@ class ShipmentSender extends NotifySender
      * @param \Psr\Log\LoggerInterface $logger
      * @param PaymentHelper $paymentHelper
      * @param ShipmentResource $shipmentResource
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
      * @param Renderer $addressRenderer
      */
     public function __construct(
@@ -50,49 +60,70 @@ class ShipmentSender extends NotifySender
         \Psr\Log\LoggerInterface $logger,
         PaymentHelper $paymentHelper,
         ShipmentResource $shipmentResource,
+        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
         Renderer $addressRenderer
     ) {
         parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger);
         $this->paymentHelper = $paymentHelper;
         $this->shipmentResource = $shipmentResource;
+        $this->globalConfig = $globalConfig;
         $this->addressRenderer = $addressRenderer;
     }
 
     /**
-     * Send email to customer
+     * Sends order shipment email to the customer.
+     *
+     * Email will be sent immediately in two cases:
+     *
+     * - if asynchronous email sending is disabled in global settings
+     * - if $forceSyncMode parameter is set to TRUE
+     *
+     * Otherwise, email will be sent later during running of
+     * corresponding cron job.
      *
      * @param Shipment $shipment
-     * @param bool $notify
-     * @param string $comment
+     * @param bool $forceSyncMode
      * @return bool
      */
-    public function send(Shipment $shipment, $notify = true, $comment = '')
+    public function send(Shipment $shipment, $forceSyncMode = false)
     {
-        $order = $shipment->getOrder();
-        if ($order->getShippingAddress()) {
-            $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
-        } else {
-            $formattedShippingAddress = '';
-        }
-        $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
-        $this->templateContainer->setTemplateVars(
-            [
-                'order' => $order,
-                'shipment' => $shipment,
-                'comment' => $comment,
-                'billing' => $order->getBillingAddress(),
-                'payment_html' => $this->getPaymentHtml($order),
-                'store' => $order->getStore(),
-                'formattedShippingAddress' => $formattedShippingAddress,
-                'formattedBillingAddress' => $formattedBillingAddress,
-            ]
-        );
-        $result = $this->checkAndSend($order, $notify);
-        if ($result) {
-            $shipment->setEmailSent(true);
-            $this->shipmentResource->saveAttribute($shipment, 'email_sent');
+        $shipment->setSendEmail(true);
+
+        if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) {
+            $order = $shipment->getOrder();
+
+            if ($order->getShippingAddress()) {
+                $formattedShippingAddress = $this->addressRenderer->format($order->getShippingAddress(), 'html');
+            } else {
+                $formattedShippingAddress = '';
+            }
+            $formattedBillingAddress = $this->addressRenderer->format($order->getBillingAddress(), 'html');
+
+            $this->templateContainer->setTemplateVars(
+                [
+                    'order' => $order,
+                    'shipment' => $shipment,
+                    'comment' => $shipment->getCustomerNoteNotify() ? $shipment->getCustomerNote() : '',
+                    'billing' => $order->getBillingAddress(),
+                    'payment_html' => $this->getPaymentHtml($order),
+                    'store' => $order->getStore(),
+                    'formattedShippingAddress' => $formattedShippingAddress,
+                    'formattedBillingAddress' => $formattedBillingAddress
+                ]
+            );
+
+            if ($this->checkAndSend($order)) {
+                $shipment->setEmailSent(true);
+
+                $this->shipmentResource->saveAttribute($shipment, ['send_email', 'email_sent']);
+
+                return true;
+            }
         }
-        return $result;
+
+        $this->shipmentResource->saveAttribute($shipment, 'send_email');
+
+        return false;
     }
 
     /**
diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php
index d88dfa1d8850a2fd04018895cb9c4417ed041c41..8317b7041d61f3e747af2b644050854b3b55174d 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice.php
@@ -12,6 +12,11 @@ use Magento\Sales\Model\EntityInterface;
 
 /**
  * @method \Magento\Sales\Model\Order\Invoice setCreatedAt(string $value)
+ * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
+ * @method string getCustomerNote()
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNoteNotify(bool $value)
+ * @method bool getCustomerNoteNotify()
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php
index ec3a0561cf262bb577f4f3a9e6f381b1ca121566..3472e9663ad337ceb64c7399b06a60e389883708 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment.php
@@ -16,6 +16,11 @@ use Magento\Sales\Model\EntityInterface;
  * @method \Magento\Sales\Model\Resource\Order\Shipment _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Shipment getResource()
  * @method \Magento\Sales\Model\Order\Shipment setCreatedAt(string $value)
+ * @method \Magento\Sales\Model\Order\Invoice setSendEmail(bool $value)
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNote(string $value)
+ * @method string getCustomerNote()
+ * @method \Magento\Sales\Model\Order\Invoice setCustomerNoteNotify(bool $value)
+ * @method bool getCustomerNoteNotify()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  */
diff --git a/app/code/Magento/Sales/Setup/InstallSchema.php b/app/code/Magento/Sales/Setup/InstallSchema.php
index e4c43d87676778164d099ad8699467373810250a..fd517941e38a02bb475a13e56ab6100dd531a911 100644
--- a/app/code/Magento/Sales/Setup/InstallSchema.php
+++ b/app/code/Magento/Sales/Setup/InstallSchema.php
@@ -876,15 +876,13 @@ class InstallSchema implements InstallSchemaInterface
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->addForeignKey(
             $installer->getFkName('sales_order', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Order'
         );
@@ -1037,22 +1035,19 @@ class InstallSchema implements InstallSchemaInterface
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->addForeignKey(
             $installer->getFkName('sales_order_grid', 'entity_id', 'sales_order', 'entity_id'),
             'entity_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_order_grid', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Order Grid'
         );
@@ -1197,7 +1192,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Order Address'
@@ -1699,15 +1693,13 @@ class InstallSchema implements InstallSchemaInterface
             'order_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_order_item', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Order Item'
         );
@@ -2050,7 +2042,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Order Payment'
@@ -2180,15 +2171,13 @@ class InstallSchema implements InstallSchemaInterface
             'order_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_shipment', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Shipment'
         );
@@ -2296,15 +2285,13 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('sales_shipment'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_shipment_grid', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Shipment Grid'
         );
@@ -2395,7 +2382,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_shipment'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Shipment Item'
@@ -2487,7 +2473,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_shipment'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Shipment Track'
@@ -2546,7 +2531,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_shipment'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Shipment Comment'
@@ -2850,15 +2834,13 @@ class InstallSchema implements InstallSchemaInterface
             'order_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_invoice', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Invoice'
         );
@@ -2996,15 +2978,13 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('sales_invoice'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_invoice_grid', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Invoice Grid'
         );
@@ -3173,7 +3153,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_invoice'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Invoice Item'
@@ -3232,7 +3211,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_invoice'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Invoice Comment'
@@ -3560,15 +3538,13 @@ class InstallSchema implements InstallSchemaInterface
             'order_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_creditmemo', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Creditmemo'
         );
@@ -3748,15 +3724,13 @@ class InstallSchema implements InstallSchemaInterface
             'entity_id',
             $installer->getTable('sales_creditmemo'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_creditmemo_grid', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Flat Creditmemo Grid'
         );
@@ -3925,7 +3899,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_creditmemo'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Creditmemo Item'
@@ -3984,7 +3957,6 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_creditmemo'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Flat Creditmemo Comment'
@@ -4066,8 +4038,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Invoiced Aggregated'
         );
@@ -4148,8 +4119,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Invoiced Aggregated Order'
         );
@@ -4296,8 +4266,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Order Aggregated Created'
         );
@@ -4394,7 +4363,6 @@ class InstallSchema implements InstallSchemaInterface
             'order_id',
             $installer->getTable('sales_order'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -4406,14 +4374,12 @@ class InstallSchema implements InstallSchemaInterface
             'parent_id',
             $installer->getTable('sales_payment_transaction'),
             'transaction_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_payment_transaction', 'payment_id', 'sales_order_payment', 'entity_id'),
             'payment_id',
             $installer->getTable('sales_order_payment'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Payment Transaction'
@@ -4489,8 +4455,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Refunded Aggregated'
         );
@@ -4565,8 +4530,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Refunded Aggregated Order'
         );
@@ -4641,8 +4605,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Shipping Aggregated'
         );
@@ -4717,8 +4680,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Sales Shipping Aggregated Order'
         );
@@ -4796,7 +4758,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -4808,7 +4769,6 @@ class InstallSchema implements InstallSchemaInterface
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Bestsellers Aggregated Daily'
@@ -4887,7 +4847,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -4899,7 +4858,6 @@ class InstallSchema implements InstallSchemaInterface
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Bestsellers Aggregated Monthly'
@@ -4978,7 +4936,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -4990,7 +4947,6 @@ class InstallSchema implements InstallSchemaInterface
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Bestsellers Aggregated Yearly'
@@ -5138,7 +5094,6 @@ class InstallSchema implements InstallSchemaInterface
             'status',
             $installer->getTable('sales_order_status'),
             'status',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Order Status Table'
@@ -5176,14 +5131,12 @@ class InstallSchema implements InstallSchemaInterface
             'status',
             $installer->getTable('sales_order_status'),
             'status',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('sales_order_status_label', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Order Status Label Table'
diff --git a/app/code/Magento/Sales/Setup/UpgradeSchema.php b/app/code/Magento/Sales/Setup/UpgradeSchema.php
index b1178f1268f0dc446d252882798158ce8920ad11..99823503bd2e1abe1ba888584a5d47885e66de6e 100644
--- a/app/code/Magento/Sales/Setup/UpgradeSchema.php
+++ b/app/code/Magento/Sales/Setup/UpgradeSchema.php
@@ -20,6 +20,7 @@ class UpgradeSchema implements UpgradeSchemaInterface
      * {@inheritdoc}
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
     {
@@ -111,6 +112,7 @@ class UpgradeSchema implements UpgradeSchemaInterface
                     );
             }
         }
+
         if (version_compare($context->getVersion(), '2.0.3') < 0) {
             $dropIncrementIndexTables = [
                 'sales_creditmemo',
@@ -155,5 +157,79 @@ class UpgradeSchema implements UpgradeSchemaInterface
                 );
             }
         }
+
+        if (version_compare($context->getVersion(), '2.0.4') < 0) {
+
+            /**
+             * Adding 'send_email' columns.
+             */
+
+            $tables = ['sales_order', 'sales_invoice', 'sales_shipment', 'sales_creditmemo'];
+
+            foreach ($tables as $table) {
+                $table = $setup->getTable($table);
+
+                $setup->getConnection()
+                    ->addColumn(
+                        $table,
+                        'send_email',
+                        [
+                            'type' => Table::TYPE_SMALLINT,
+                            'after' => 'email_sent',
+                            'comment' => 'Send Email',
+                            'unsigned' => true
+                        ]
+                    );
+
+                $setup->getConnection()
+                    ->addIndex($table, $setup->getIdxName($table, ['email_sent']), 'email_sent');
+
+                $setup->getConnection()
+                    ->addIndex($table, $setup->getIdxName($table, ['send_email']), 'send_email');
+            }
+
+            /**
+             * Adding 'customer_note' columns.
+             */
+
+            $tables = ['sales_invoice', 'sales_shipment', 'sales_creditmemo'];
+
+            foreach ($tables as $table) {
+                $table = $setup->getTable($table);
+
+                $setup->getConnection()
+                    ->addColumn(
+                        $table,
+                        'customer_note',
+                        [
+                            'type' => Table::TYPE_TEXT,
+                            'after' => 'updated_at',
+                            'comment' => 'Customer Note'
+                        ]
+                    );
+            }
+
+            /**
+             * Adding 'customer_note_notify' columns.
+             */
+
+            $tables = ['sales_invoice', 'sales_shipment', 'sales_creditmemo'];
+
+            foreach ($tables as $table) {
+                $table = $setup->getTable($table);
+
+                $setup->getConnection()
+                    ->addColumn(
+                        $table,
+                        'customer_note_notify',
+                        [
+                            'type' => Table::TYPE_SMALLINT,
+                            'after' => 'customer_note',
+                            'comment' => 'Customer Note Notify',
+                            'unsigned' => true
+                        ]
+                    );
+            }
+        }
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..69f3f6e0df310d27dc7c7c6774ad5a62ca1e82cb
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Email/AsyncSendingTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Test\Unit\Model\Config\Backend\Email;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Unit test of backend model for global configuration value
+ * 'sales_email/general/async_sending'.
+ */
+class AsyncSendingTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Config\Backend\Email\AsyncSending
+     */
+    protected $object;
+
+    /**
+     * @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $config;
+
+    /**
+     * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\Event\Manager\Proxy|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManager;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->config = $this->getMock('Magento\Framework\App\Config', [], [], '', false);
+
+        $this->eventManager = $this->getMock('Magento\Framework\Event\Manager\Proxy', [], [], '', false);
+
+        $this->context = $this->getMock('Magento\Framework\Model\Context', ['getEventDispatcher'], [], '', false);
+        $this->context->expects($this->any())->method('getEventDispatcher')->willReturn($this->eventManager);
+
+        $this->object = $objectManager->getObject(
+            '\Magento\Sales\Model\Config\Backend\Email\AsyncSending',
+            [
+                'config' => $this->config,
+                'context' => $this->context
+            ]
+        );
+    }
+
+    /**
+     * @param int $value
+     * @param int $oldValue
+     * @param string $eventName
+     * @dataProvider afterSaveDataProvider
+     * @return void
+     */
+    public function testAfterSave($value, $oldValue, $eventName)
+    {
+        $path = 'sales_email/general/async_sending';
+        $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT;
+
+        $this->object->setData(['value' => $value, 'path' => $path, 'scope' => $scope]);
+
+        $this->config->expects($this->once())->method('getValue')->with($path, $scope)->willReturn($oldValue);
+
+        if ($value == $oldValue) {
+            $this->eventManager->expects($this->never())->method('dispatch');
+        } else {
+            $this->eventManager->expects($this->once())->method('dispatch')->with($eventName);
+        }
+
+        $this->object->afterSave();
+    }
+
+    /**
+     * @return array
+     */
+    public function afterSaveDataProvider()
+    {
+        return [
+            [0, 0, null],
+            [1, 1, null],
+            [0, 1, 'config_data_sales_email_general_async_sending_disabled'],
+            [1, 0, 'config_data_sales_email_general_async_sending_enabled']
+        ];
+    }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Observer/SendEmailsTest.php b/app/code/Magento/Sales/Test/Unit/Model/Observer/SendEmailsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b3e4a9905a17f761eb6b763df933dabf5630d6b
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Model/Observer/SendEmailsTest.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Test\Unit\Model\Observer;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Unit test of sales emails sending observer.
+ */
+class SendEmailsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Subject of testing.
+     *
+     * @var \Magento\Sales\Model\Observer\SendEmails
+     */
+    protected $object;
+
+    /**
+     * Email sender model mock.
+     *
+     * @var \Magento\Sales\Model\Order\Email\Sender|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $emailSender;
+
+    /**
+     * Entity resource model mock.
+     *
+     * @var \Magento\Sales\Model\Resource\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityResource;
+
+    /**
+     * Entity collection model mock.
+     *
+     * @var \Magento\Sales\Model\Resource\Collection\AbstractCollection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityCollection;
+
+    /**
+     * Global configuration storage mock.
+     *
+     * @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $globalConfig;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->emailSender = $this->getMock(
+            'Magento\Sales\Model\Order\Email\Sender',
+            ['send'],
+            [],
+            '',
+            false
+        );
+
+        $this->entityResource = $this->getMockForAbstractClass(
+            'Magento\Sales\Model\Resource\EntityAbstract',
+            [],
+            '',
+            false,
+            false,
+            true,
+            ['save']
+        );
+
+        $this->entityCollection = $this->getMockForAbstractClass(
+            'Magento\Sales\Model\Resource\Collection\AbstractCollection',
+            [],
+            '',
+            false,
+            false,
+            true,
+            ['addFieldToFilter', 'getItems']
+        );
+
+        $this->globalConfig = $this->getMock(
+            'Magento\Framework\App\Config',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->object = $objectManager->getObject(
+            'Magento\Sales\Model\Observer\SendEmails',
+            [
+                'emailSender' => $this->emailSender,
+                'entityResource' => $this->entityResource,
+                'entityCollection' => $this->entityCollection,
+                'globalConfig' => $this->globalConfig
+            ]
+        );
+    }
+
+    /**
+     * @param int $configValue
+     * @param array|null $collectionItems
+     * @param bool|null $emailSendingResult
+     * @dataProvider executeDataProvider
+     * @return void
+     */
+    public function testExecute($configValue, $collectionItems, $emailSendingResult)
+    {
+        $path = 'sales_email/general/async_sending';
+
+        $this->globalConfig
+            ->expects($this->once())
+            ->method('getValue')
+            ->with($path)
+            ->willReturn($configValue);
+
+        if ($configValue) {
+            $this->entityCollection
+                ->expects($this->at(0))
+                ->method('addFieldToFilter')
+                ->with('send_email', ['eq' => 1]);
+
+            $this->entityCollection
+                ->expects($this->at(1))
+                ->method('addFieldToFilter')
+                ->with('email_sent', ['null' => true]);
+
+            $this->entityCollection
+                ->expects($this->any())
+                ->method('getItems')
+                ->willReturn($collectionItems);
+
+            if ($collectionItems) {
+                /** @var \Magento\Sales\Model\AbstractModel|\PHPUnit_Framework_MockObject_MockObject $collectionItem */
+                $collectionItem = $collectionItems[0];
+
+                $this->emailSender
+                    ->expects($this->once())
+                    ->method('send')
+                    ->with($collectionItem, true)
+                    ->willReturn($emailSendingResult);
+
+                if ($emailSendingResult) {
+                    $collectionItem
+                        ->expects($this->once())
+                        ->method('setEmailSent')
+                        ->with(true)
+                        ->willReturn($collectionItem);
+
+                    $this->entityResource
+                        ->expects($this->once())
+                        ->method('save')
+                        ->with($collectionItem);
+                }
+            }
+        }
+
+        $this->object->execute();
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        $entityModel = $this->getMockForAbstractClass(
+            'Magento\Sales\Model\AbstractModel',
+            [],
+            '',
+            false,
+            false,
+            true,
+            ['setEmailSent']
+        );
+
+        return [
+            [1, [$entityModel], true],
+            [1, [$entityModel], false],
+            [1, [], null],
+            [0, null, null]
+        ];
+    }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
index f57cac671fa583cd989e9251664ad6a1113a3c7d..cd70e51424497d16585475b55edaab6d526e7cef 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php
@@ -10,6 +10,11 @@ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender;
  */
 abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Sales\Model\Order\Email\Sender|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $senderMock;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -36,12 +41,24 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
     protected $orderMock;
 
     /**
-     * @var \Magento\Sales\Model\Order\Address\Renderer | \PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $addressRendererMock;
+    protected $paymentHelper;
 
     /**
-     * @var \Magento\Sales\Model\Order\Address | \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Order\Address\Renderer|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $addressRenderer;
+
+    /**
+     * Global configuration storage mock.
+     *
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $globalConfig;
+
+    /**
+     * @var \Magento\Sales\Model\Order\Address|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $addressMock;
 
@@ -52,6 +69,14 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
 
     public function stepMockSetup()
     {
+        $this->senderMock = $this->getMock(
+            'Magento\Sales\Model\Order\Email\Sender',
+            ['send', 'sendCopyTo'],
+            [],
+            '',
+            false
+        );
+
         $this->senderBuilderFactoryMock = $this->getMock(
             '\Magento\Sales\Model\Order\Email\SenderBuilderFactory',
             ['create'],
@@ -77,20 +102,46 @@ abstract class AbstractSenderTest extends \PHPUnit_Framework_TestCase
 
         $this->orderMock = $this->getMock(
             '\Magento\Sales\Model\Order',
-            [],
+            [
+                'getStore', 'getBillingAddress', 'getPayment',
+                '__wakeup', 'getCustomerIsGuest', 'getCustomerName',
+                'getCustomerEmail', 'getShippingAddress', 'setSendEmail',
+                'setEmailSent'
+            ],
             [],
             '',
             false
         );
-
         $this->orderMock->expects($this->any())
             ->method('getStore')
             ->will($this->returnValue($this->storeMock));
+        $paymentInfoMock = $this->getMock(
+            '\Magento\Payment\Model\Info',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->orderMock->expects($this->any())
+            ->method('getPayment')
+            ->will($this->returnValue($paymentInfoMock));
 
-
-        $this->addressRendererMock = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false);
+        $this->addressRenderer = $this->getMock('Magento\Sales\Model\Order\Address\Renderer', [], [], '', false);
         $this->addressMock = $this->getMock('Magento\Sales\Model\Order\Address', [], [], '', false);
-        $this->addressRendererMock->expects($this->any())->method('format')->willReturn(1);
+
+        $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false);
+        $this->paymentHelper->expects($this->any())
+            ->method('getInfoBlockHtml')
+            ->will($this->returnValue('payment'));
+
+        $this->globalConfig = $this->getMock(
+            'Magento\Framework\App\Config',
+            ['getValue'],
+            [],
+            '',
+            false
+        );
+
         $this->loggerMock = $this->getMock(
             '\Psr\Log\LoggerInterface',
             [],
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
index c15aed06c125e85fe4732a483105522167522fde..977ded72038ee29f205fa6981c1f534dfdae6120 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoCommentSenderTest.php
@@ -26,6 +26,7 @@ class CreditmemoCommentSenderTest extends AbstractSenderTest
     {
         $this->stepMockSetup();
         $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\CreditmemoCommentIdentity');
+        $this->addressRenderer->expects($this->any())->method('format')->willReturn(1);
         $this->creditmemoMock = $this->getMock(
             '\Magento\Sales\Model\Order\Creditmemo',
             ['getStore', '__wakeup', 'getOrder'],
@@ -44,7 +45,7 @@ class CreditmemoCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRendererMock
+            $this->addressRenderer
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
index eff59e2afe8a99999fb54d326754148fd7192968..cfe7bfc22e54f51db6edc23e02859488612fd11b 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender;
 
-use \Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
+use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
 
 class CreditmemoSenderTest extends AbstractSenderTest
 {
@@ -15,52 +15,34 @@ class CreditmemoSenderTest extends AbstractSenderTest
     protected $sender;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Order\Creditmemo|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $creditmemoMock;
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $paymentHelper;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Resource\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $creditmemoResource;
+    protected $creditmemoResourceMock;
 
-    /**
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
     protected function setUp()
     {
         $this->stepMockSetup();
-        $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false);
-        $this->paymentHelper->expects($this->any())
-            ->method('getInfoBlockHtml')
-            ->will($this->returnValue('payment'));
 
-        $this->creditmemoResource = $this->getMock(
+        $this->creditmemoResourceMock = $this->getMock(
             '\Magento\Sales\Model\Resource\Order\Creditmemo',
-            [],
+            ['saveAttribute'],
             [],
             '',
             false
         );
-        $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity');
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
 
         $this->creditmemoMock = $this->getMock(
             '\Magento\Sales\Model\Order\Creditmemo',
-            ['getStore', '__wakeup', 'getOrder'],
+            [
+                'getStore', '__wakeup', 'getOrder',
+                'setSendEmail', 'setEmailSent', 'getCustomerNoteNotify',
+                'getCustomerNote'
+            ],
             [],
             '',
             false
@@ -71,95 +53,156 @@ class CreditmemoSenderTest extends AbstractSenderTest
         $this->creditmemoMock->expects($this->any())
             ->method('getOrder')
             ->will($this->returnValue($this->orderMock));
+
+        $this->identityContainerMock = $this->getMock(
+            '\Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity',
+            ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'],
+            [],
+            '',
+            false
+        );
+        $this->identityContainerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+
         $this->sender = new CreditmemoSender(
             $this->templateContainerMock,
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
             $this->paymentHelper,
-            $this->creditmemoResource,
-            $this->addressRendererMock
+            $this->creditmemoResourceMock,
+            $this->globalConfig,
+            $this->addressRenderer
         );
     }
 
-    public function testSendFalse()
-    {
-        $this->stepAddressFormat($this->addressMock);
-        $result = $this->sender->send($this->creditmemoMock);
-        $this->assertFalse($result);
-    }
-
-    public function testSendTrueWithCustomerCopy()
+    /**
+     * @param int $configValue
+     * @param bool|null $forceSyncMode
+     * @param bool|null $customerNoteNotify
+     * @param bool|null $emailSendingResult
+     * @dataProvider sendDataProvider
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $emailSendingResult)
     {
-        $billingAddress = $this->addressMock;
-        $this->stepAddressFormat($this->addressMock);
         $comment = 'comment_test';
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
+        $address = 'address_test';
+        $configPath = 'sales_email/general/async_sending';
+
+        $this->creditmemoMock->expects($this->once())
+            ->method('setSendEmail')
+            ->with(true);
+
+        $this->globalConfig->expects($this->once())
+            ->method('getValue')
+            ->with($configPath)
+            ->willReturn($configValue);
+
+        if (!$configValue || $forceSyncMode) {
+            $addressMock = $this->getMock(
+                'Magento\Sales\Model\Order\Address',
+                [],
+                [],
+                '',
+                false
+            );
+
+            $this->addressRenderer->expects($this->any())
+                ->method('format')
+                ->with($addressMock, 'html')
+                ->willReturn($address);
+
+            $this->orderMock->expects($this->any())
+                ->method('getBillingAddress')
+                ->willReturn($addressMock);
+
+            $this->orderMock->expects($this->any())
+                ->method('getShippingAddress')
+                ->willReturn($addressMock);
+
+            $this->creditmemoMock->expects($this->once())
+                ->method('getCustomerNoteNotify')
+                ->willReturn($customerNoteNotify);
+
+            $this->creditmemoMock->expects($this->any())
+                ->method('getCustomerNote')
+                ->willReturn($comment);
+
+            $this->templateContainerMock->expects($this->once())
+                ->method('setTemplateVars')
+                ->with(
                     [
                         'order' => $this->orderMock,
                         'creditmemo' => $this->creditmemoMock,
-                        'comment' => $comment,
-                        'billing' => $billingAddress,
+                        'comment' => $customerNoteNotify ? $comment : '',
+                        'billing' => $addressMock,
                         'payment_html' => 'payment',
                         'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
+                        'formattedShippingAddress' => $address,
+                        'formattedBillingAddress' => $address
                     ]
-                )
+                );
+
+            $this->identityContainerMock->expects($this->once())
+                ->method('isEnabled')
+                ->willReturn($emailSendingResult);
+
+            if ($emailSendingResult) {
+                $this->senderBuilderFactoryMock->expects($this->once())
+                    ->method('create')
+                    ->willReturn($this->senderMock);
+
+                $this->senderMock->expects($this->once())->method('send');
+
+                $this->senderMock->expects($this->once())->method('sendCopyTo');
+
+                $this->creditmemoMock->expects($this->once())
+                    ->method('setEmailSent')
+                    ->with(true);
+
+                $this->creditmemoResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->creditmemoMock, ['send_email', 'email_sent']);
+
+                $this->assertTrue(
+                    $this->sender->send($this->creditmemoMock)
+                );
+            } else {
+                $this->creditmemoResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->creditmemoMock, 'send_email');
+
+                $this->assertFalse(
+                    $this->sender->send($this->creditmemoMock)
+                );
+            }
+        } else {
+            $this->creditmemoResourceMock->expects($this->once())
+                ->method('saveAttribute')
+                ->with($this->creditmemoMock, 'send_email');
+
+            $this->assertFalse(
+                $this->sender->send($this->creditmemoMock)
             );
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
-        $this->stepSendWithoutSendCopy();
-        $result = $this->sender->send($this->creditmemoMock, true, $comment);
-        $this->assertTrue($result);
+        }
     }
 
-    public function testSendTrueWithoutCustomerCopy()
+    /**
+     * @return array
+     */
+    public function sendDataProvider()
     {
-        $billingAddress = $this->addressMock;
-        $this->stepAddressFormat($billingAddress);
-        $comment = 'comment_test';
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
-                    [
-                        'order' => $this->orderMock,
-                        'creditmemo' => $this->creditmemoMock,
-                        'billing' => $billingAddress,
-                        'payment_html' => 'payment',
-                        'comment' => $comment,
-                        'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
-                    ]
-                )
-            );
-        $this->stepSendWithCallSendCopyTo();
-        $result = $this->sender->send($this->creditmemoMock, false, $comment);
-        $this->assertTrue($result);
+        return [
+            [0, 0, 1, true],
+            [0, 0, 0, true],
+            [0, 0, 1, false],
+            [0, 0, 0, false],
+            [0, 1, 1, true],
+            [0, 1, 0, true],
+            [1, null, null, null]
+        ];
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
index 28888804481dc704bff9ca1455c25688db95fb84..30b838341b5ce16a3d733839f911ee1014c2ccfe 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceCommentSenderTest.php
@@ -40,6 +40,8 @@ class InvoiceCommentSenderTest extends AbstractSenderTest
 
         $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\InvoiceCommentIdentity');
 
+        $this->addressRenderer->expects($this->any())->method('format')->willReturn(1);
+
         $this->invoiceMock = $this->getMock(
             '\Magento\Sales\Model\Order\Invoice',
             ['getStore', '__wakeup', 'getOrder'],
@@ -59,7 +61,7 @@ class InvoiceCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRendererMock
+            $this->addressRenderer
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
index 3cb4e27fc43121dec895f70e6e436bbebac6c58f..35cb0e84b6566f2e74c0f17f20d918e8a88945a9 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender;
 
-use \Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
+use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
 
 class InvoiceSenderTest extends AbstractSenderTest
 {
@@ -15,54 +15,34 @@ class InvoiceSenderTest extends AbstractSenderTest
     protected $sender;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Order\Invoice|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $invoiceMock;
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $paymentHelper;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Resource\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $invoiceResource;
+    protected $invoiceResourceMock;
 
-    /**
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
     protected function setUp()
     {
         $this->stepMockSetup();
-        $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false);
-        $this->paymentHelper->expects($this->any())
-            ->method('getInfoBlockHtml')
-            ->will($this->returnValue('payment'));
 
-        $this->invoiceResource = $this->getMock(
+        $this->invoiceResourceMock = $this->getMock(
             '\Magento\Sales\Model\Resource\Order\Invoice',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\InvoiceIdentity');
-
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
+            ['saveAttribute'],
             [],
             '',
             false
         );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
 
         $this->invoiceMock = $this->getMock(
             '\Magento\Sales\Model\Order\Invoice',
-            ['getStore', '__wakeup', 'getOrder'],
+            [
+                'getStore', '__wakeup', 'getOrder',
+                'setSendEmail', 'setEmailSent', 'getCustomerNoteNotify',
+                'getCustomerNote'
+            ],
             [],
             '',
             false
@@ -74,100 +54,155 @@ class InvoiceSenderTest extends AbstractSenderTest
             ->method('getOrder')
             ->will($this->returnValue($this->orderMock));
 
+        $this->identityContainerMock = $this->getMock(
+            '\Magento\Sales\Model\Order\Email\Container\InvoiceIdentity',
+            ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'],
+            [],
+            '',
+            false
+        );
+        $this->identityContainerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+
         $this->sender = new InvoiceSender(
             $this->templateContainerMock,
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
             $this->paymentHelper,
-            $this->invoiceResource,
-            $this->addressRendererMock
+            $this->invoiceResourceMock,
+            $this->globalConfig,
+            $this->addressRenderer
         );
     }
 
-    public function testSendFalse()
-    {
-        $billingAddress = $this->addressMock;
-        $this->stepAddressFormat($billingAddress);
-        $result = $this->sender->send($this->invoiceMock);
-        $this->assertFalse($result);
-    }
-
-    public function testSendTrueWithCustomerCopy()
+    /**
+     * @param int $configValue
+     * @param bool|null $forceSyncMode
+     * @param bool|null $customerNoteNotify
+     * @param bool|null $emailSendingResult
+     * @dataProvider sendDataProvider
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $emailSendingResult)
     {
-        $billingAddress = $this->addressMock;
-        $this->stepAddressFormat($billingAddress);
         $comment = 'comment_test';
+        $address = 'address_test';
+        $configPath = 'sales_email/general/async_sending';
+
+        $this->invoiceMock->expects($this->once())
+            ->method('setSendEmail')
+            ->with(true);
+
+        $this->globalConfig->expects($this->once())
+            ->method('getValue')
+            ->with($configPath)
+            ->willReturn($configValue);
+
+        if (!$configValue || $forceSyncMode) {
+            $addressMock = $this->getMock(
+                'Magento\Sales\Model\Order\Address',
+                [],
+                [],
+                '',
+                false
+            );
+
+            $this->addressRenderer->expects($this->any())
+                ->method('format')
+                ->with($addressMock, 'html')
+                ->willReturn($address);
+
+            $this->orderMock->expects($this->any())
+                ->method('getBillingAddress')
+                ->willReturn($addressMock);
+
+            $this->orderMock->expects($this->any())
+                ->method('getShippingAddress')
+                ->willReturn($addressMock);
 
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
+            $this->invoiceMock->expects($this->once())
+                ->method('getCustomerNoteNotify')
+                ->willReturn($customerNoteNotify);
+
+            $this->invoiceMock->expects($this->any())
+                ->method('getCustomerNote')
+                ->willReturn($comment);
+
+            $this->templateContainerMock->expects($this->once())
+                ->method('setTemplateVars')
+                ->with(
                     [
                         'order' => $this->orderMock,
                         'invoice' => $this->invoiceMock,
-                        'comment' => $comment,
-                        'billing' => $billingAddress,
+                        'comment' => $customerNoteNotify ? $comment : '',
+                        'billing' => $addressMock,
                         'payment_html' => 'payment',
                         'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
+                        'formattedShippingAddress' => $address,
+                        'formattedBillingAddress' => $address
                     ]
-                )
+                );
+
+            $this->identityContainerMock->expects($this->once())
+                ->method('isEnabled')
+                ->willReturn($emailSendingResult);
+
+            if ($emailSendingResult) {
+                $this->senderBuilderFactoryMock->expects($this->once())
+                    ->method('create')
+                    ->willReturn($this->senderMock);
+
+                $this->senderMock->expects($this->once())->method('send');
+
+                $this->senderMock->expects($this->once())->method('sendCopyTo');
+
+                $this->invoiceMock->expects($this->once())
+                    ->method('setEmailSent')
+                    ->with(true);
+
+                $this->invoiceResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->invoiceMock, ['send_email', 'email_sent']);
+
+                $this->assertTrue(
+                    $this->sender->send($this->invoiceMock)
+                );
+            } else {
+                $this->invoiceResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->invoiceMock, 'send_email');
+
+                $this->assertFalse(
+                    $this->sender->send($this->invoiceMock)
+                );
+            }
+        } else {
+            $this->invoiceResourceMock->expects($this->once())
+                ->method('saveAttribute')
+                ->with($this->invoiceMock, 'send_email');
+
+            $this->assertFalse(
+                $this->sender->send($this->invoiceMock)
             );
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
-        $this->stepSendWithoutSendCopy();
-        $result = $this->sender->send($this->invoiceMock, true, $comment);
-        $this->assertTrue($result);
+        }
     }
 
-    public function testSendTrueWithoutCustomerCopy()
+    /**
+     * @return array
+     */
+    public function sendDataProvider()
     {
-        $billingAddress = $this->addressMock;
-        $this->stepAddressFormat($billingAddress);
-        $comment = 'comment_test';
-
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
-                    [
-                        'order' => $this->orderMock,
-                        'invoice' => $this->invoiceMock,
-                        'billing' => $billingAddress,
-                        'payment_html' => 'payment',
-                        'comment' => $comment,
-                        'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
-                    ]
-                )
-            );
-        $this->stepSendWithCallSendCopyTo();
-        $result = $this->sender->send($this->invoiceMock, false, $comment);
-        $this->assertTrue($result);
+        return [
+            [0, 0, 1, true],
+            [0, 0, 0, true],
+            [0, 0, 1, false],
+            [0, 0, 0, false],
+            [0, 1, 1, true],
+            [0, 1, 0, true],
+            [1, null, null, null]
+        ];
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
index 1ddc4e3724cd4050d2834987243c202baf9e126f..9bb5745162152cf85610abaa6cd8af1564586c7d 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderCommentSenderTest.php
@@ -18,12 +18,13 @@ class OrderCommentSenderTest extends AbstractSenderTest
     {
         $this->stepMockSetup();
         $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity');
+        $this->addressRenderer->expects($this->any())->method('format')->willReturn(1);
         $this->sender = new OrderCommentSender(
             $this->templateContainerMock,
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRendererMock
+            $this->addressRenderer
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
index b6453f501acb007a92b30ed940b4f003b454f8c7..5350c1924f023c6055e59eec341cb024acb687ca 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender;
 
-use \Magento\Sales\Model\Order\Email\Sender\OrderSender;
+use Magento\Sales\Model\Order\Email\Sender\OrderSender;
 
 class OrderSenderTest extends AbstractSenderTest
 {
@@ -15,42 +15,32 @@ class OrderSenderTest extends AbstractSenderTest
     protected $sender;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Resource\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $paymentHelper;
+    protected $orderResourceMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $orderResource;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $loggerMock;
-    
     protected function setUp()
     {
         $this->stepMockSetup();
-        $this->paymentHelper = $this->getMock(
-            '\Magento\Payment\Helper\Data',
-            ['getInfoBlockHtml'],
+
+        $this->orderResourceMock = $this->getMock(
+            '\Magento\Sales\Model\Resource\Order',
+            ['saveAttribute'],
             [],
             '',
             false
         );
-        $this->paymentHelper->expects($this->any())
-            ->method('getInfoBlockHtml')
-            ->will($this->returnValue('payment'));
 
-        $this->orderResource = $this->getMock(
-            '\Magento\Sales\Model\Resource\Order',
-            [],
+        $this->identityContainerMock = $this->getMock(
+            '\Magento\Sales\Model\Order\Email\Container\OrderIdentity',
+            ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'],
             [],
             '',
             false
         );
-        $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\OrderIdentity');
+        $this->identityContainerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
 
         $this->sender = new OrderSender(
             $this->templateContainerMock,
@@ -58,110 +48,125 @@ class OrderSenderTest extends AbstractSenderTest
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
             $this->paymentHelper,
-            $this->orderResource,
-            $this->addressRendererMock
+            $this->orderResourceMock,
+            $this->globalConfig,
+            $this->addressRenderer
         );
     }
 
-    public function testSendFalse()
-    {
-        $this->stepAddressFormat($this->addressMock);
-        $result = $this->sender->send($this->orderMock);
-        $this->assertFalse($result);
-    }
-
-    public function testSendTrueForCustomer()
+    /**
+     * @param int $configValue
+     * @param bool|null $forceSyncMode
+     * @param bool|null $emailSendingResult
+     * @dataProvider sendDataProvider
+     * @return void
+     */
+    public function testSend($configValue, $forceSyncMode, $emailSendingResult)
     {
-        $billingAddress = $this->addressMock;
+        $address = 'address_test';
+        $configPath = 'sales_email/general/async_sending';
 
         $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-        $this->stepAddressFormat($billingAddress);
+            ->method('setSendEmail')
+            ->with(true);
 
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
-                    [
-                        'order' => $this->orderMock,
-                        'billing' => $billingAddress,
-                        'payment_html' => 'payment',
-                        'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
-                    ]
-                )
+        $this->globalConfig->expects($this->once())
+            ->method('getValue')
+            ->with($configPath)
+            ->willReturn($configValue);
+
+        if (!$configValue || $forceSyncMode) {
+            $this->identityContainerMock->expects($this->once())
+                ->method('isEnabled')
+                ->willReturn($emailSendingResult);
+
+            if ($emailSendingResult) {
+                $addressMock = $this->getMock(
+                    'Magento\Sales\Model\Order\Address',
+                    [],
+                    [],
+                    '',
+                    false
+                );
+
+                $this->addressRenderer->expects($this->any())
+                    ->method('format')
+                    ->with($addressMock, 'html')
+                    ->willReturn($address);
+
+                $this->orderMock->expects($this->any())
+                    ->method('getBillingAddress')
+                    ->willReturn($addressMock);
+
+                $this->orderMock->expects($this->any())
+                    ->method('getShippingAddress')
+                    ->willReturn($addressMock);
+
+                $this->templateContainerMock->expects($this->once())
+                    ->method('setTemplateVars')
+                    ->with(
+                        [
+                            'order' => $this->orderMock,
+                            'billing' => $addressMock,
+                            'payment_html' => 'payment',
+                            'store' => $this->storeMock,
+                            'formattedShippingAddress' => $address,
+                            'formattedBillingAddress' => $address
+                        ]
+                    );
+
+                $this->senderBuilderFactoryMock->expects($this->once())
+                    ->method('create')
+                    ->willReturn($this->senderMock);
+
+                $this->senderMock->expects($this->once())->method('send');
+
+                $this->senderMock->expects($this->once())->method('sendCopyTo');
+
+                $this->orderMock->expects($this->once())
+                    ->method('setEmailSent')
+                    ->with(true);
+
+                $this->orderResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->orderMock, ['send_email', 'email_sent']);
+
+                $this->assertTrue(
+                    $this->sender->send($this->orderMock)
+                );
+            } else {
+                $this->orderResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->orderMock, 'send_email');
+
+                $this->assertFalse(
+                    $this->sender->send($this->orderMock)
+                );
+            }
+        } else {
+            $this->orderResourceMock->expects($this->once())
+                ->method('saveAttribute')
+                ->with($this->orderMock, 'send_email');
+
+            $this->assertFalse(
+                $this->sender->send($this->orderMock)
             );
-        $this->stepSend($this->once(), $this->once());
-        $result = $this->sender->send($this->orderMock);
-        $this->assertTrue($result);
+        }
     }
 
-    public function testSendTrueForGuest()
+    /**
+     * @return array
+     */
+    public function sendDataProvider()
     {
-        $billingAddress = $this->getMock(
-            '\Magento\Sales\Model\Order\Address',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->stepAddressFormat($billingAddress);
-        $billingAddress->expects($this->any())
-            ->method('getName')
-            ->will($this->returnValue('name'));
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(true));
-        $this->orderMock->expects($this->any())
-            ->method('getBillingAddress')
-            ->will($this->returnValue($billingAddress));
-
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
-                    [
-                        'order' => $this->orderMock,
-                        'billing' => $billingAddress,
-                        'payment_html' => 'payment',
-                        'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
-                    ]
-                )
-            );
-        $this->stepSend($this->once(), $this->once());
-        $result = $this->sender->send($this->orderMock);
-        $this->assertTrue($result);
+        return [
+            [0, 0, true],
+            [0, 0, true],
+            [0, 0, false],
+            [0, 0, false],
+            [0, 1, true],
+            [0, 1, true],
+            [1, null, null, null]
+        ];
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
index 6d4c4f26fc03078f2d05510cf28b07ce15af2d7a..0a69bb2fcf85d7eae3c0f0841ee17be8afdd1221 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentCommentSenderTest.php
@@ -23,6 +23,7 @@ class ShipmentCommentSenderTest extends AbstractSenderTest
     {
         $this->stepMockSetup();
         $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\ShipmentCommentIdentity');
+        $this->addressRenderer->expects($this->any())->method('format')->willReturn(1);
         $this->shipmentMock = $this->getMock(
             '\Magento\Sales\Model\Order\Shipment',
             ['getStore', '__wakeup', 'getOrder'],
@@ -42,7 +43,7 @@ class ShipmentCommentSenderTest extends AbstractSenderTest
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
-            $this->addressRendererMock
+            $this->addressRenderer
         );
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
index 1f57f234e409c43c25f1089980aa88fbf389daa6..a13619f0423eaaa9a0f0ee3636c0c999454a0a9c 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender;
 
-use \Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
+use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
 
 class ShipmentSenderTest extends AbstractSenderTest
 {
@@ -15,54 +15,34 @@ class ShipmentSenderTest extends AbstractSenderTest
     protected $sender;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $shipmentMock;
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $paymentHelper;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Resource\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $shipmentResource;
+    protected $shipmentResourceMock;
 
-    /**
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
     protected function setUp()
     {
         $this->stepMockSetup();
-        $this->paymentHelper = $this->getMock('\Magento\Payment\Helper\Data', ['getInfoBlockHtml'], [], '', false);
-        $this->paymentHelper->expects($this->any())
-            ->method('getInfoBlockHtml')
-            ->will($this->returnValue('payment'));
 
-        $this->shipmentResource = $this->getMock(
+        $this->shipmentResourceMock = $this->getMock(
             '\Magento\Sales\Model\Resource\Order\Shipment',
-            [],
-            [],
-            '',
-            false
-        );
-
-        $this->stepIdentityContainerInit('\Magento\Sales\Model\Order\Email\Container\ShipmentIdentity');
-
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
+            ['saveAttribute'],
             [],
             '',
             false
         );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
 
         $this->shipmentMock = $this->getMock(
             '\Magento\Sales\Model\Order\Shipment',
-            ['getStore', '__wakeup', 'getOrder'],
+            [
+                'getStore', '__wakeup', 'getOrder',
+                'setSendEmail', 'setEmailSent', 'getCustomerNoteNotify',
+                'getCustomerNote'
+            ],
             [],
             '',
             false
@@ -74,99 +54,155 @@ class ShipmentSenderTest extends AbstractSenderTest
             ->method('getOrder')
             ->will($this->returnValue($this->orderMock));
 
+        $this->identityContainerMock = $this->getMock(
+            '\Magento\Sales\Model\Order\Email\Container\ShipmentIdentity',
+            ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId'],
+            [],
+            '',
+            false
+        );
+        $this->identityContainerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+
         $this->sender = new ShipmentSender(
             $this->templateContainerMock,
             $this->identityContainerMock,
             $this->senderBuilderFactoryMock,
             $this->loggerMock,
             $this->paymentHelper,
-            $this->shipmentResource,
-            $this->addressRendererMock
+            $this->shipmentResourceMock,
+            $this->globalConfig,
+            $this->addressRenderer
         );
     }
 
-    public function testSendFalse()
-    {
-        $this->stepAddressFormat($this->addressMock);
-        $result = $this->sender->send($this->shipmentMock);
-        $this->assertFalse($result);
-    }
-
-    public function testSendTrueWithCustomerCopy()
+    /**
+     * @param int $configValue
+     * @param bool|null $forceSyncMode
+     * @param bool|null $customerNoteNotify
+     * @param bool|null $emailSendingResult
+     * @dataProvider sendDataProvider
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $emailSendingResult)
     {
-        $billingAddress = $this->addressMock;
         $comment = 'comment_test';
+        $address = 'address_test';
+        $configPath = 'sales_email/general/async_sending';
+
+        $this->shipmentMock->expects($this->once())
+            ->method('setSendEmail')
+            ->with(true);
+
+        $this->globalConfig->expects($this->once())
+            ->method('getValue')
+            ->with($configPath)
+            ->willReturn($configValue);
+
+        if (!$configValue || $forceSyncMode) {
+            $addressMock = $this->getMock(
+                'Magento\Sales\Model\Order\Address',
+                [],
+                [],
+                '',
+                false
+            );
+
+            $this->addressRenderer->expects($this->any())
+                ->method('format')
+                ->with($addressMock, 'html')
+                ->willReturn($address);
+
+            $this->orderMock->expects($this->any())
+                ->method('getBillingAddress')
+                ->willReturn($addressMock);
+
+            $this->orderMock->expects($this->any())
+                ->method('getShippingAddress')
+                ->willReturn($addressMock);
 
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-        $this->stepAddressFormat($billingAddress);
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
+            $this->shipmentMock->expects($this->once())
+                ->method('getCustomerNoteNotify')
+                ->willReturn($customerNoteNotify);
+
+            $this->shipmentMock->expects($this->any())
+                ->method('getCustomerNote')
+                ->willReturn($comment);
+
+            $this->templateContainerMock->expects($this->once())
+                ->method('setTemplateVars')
+                ->with(
                     [
                         'order' => $this->orderMock,
                         'shipment' => $this->shipmentMock,
-                        'comment' => $comment,
-                        'billing' => $billingAddress,
+                        'comment' => $customerNoteNotify ? $comment : '',
+                        'billing' => $addressMock,
                         'payment_html' => 'payment',
                         'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
+                        'formattedShippingAddress' => $address,
+                        'formattedBillingAddress' => $address
                     ]
-                )
+                );
+
+            $this->identityContainerMock->expects($this->once())
+                ->method('isEnabled')
+                ->willReturn($emailSendingResult);
+
+            if ($emailSendingResult) {
+                $this->senderBuilderFactoryMock->expects($this->once())
+                    ->method('create')
+                    ->willReturn($this->senderMock);
+
+                $this->senderMock->expects($this->once())->method('send');
+
+                $this->senderMock->expects($this->once())->method('sendCopyTo');
+
+                $this->shipmentMock->expects($this->once())
+                    ->method('setEmailSent')
+                    ->with(true);
+
+                $this->shipmentResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->shipmentMock, ['send_email', 'email_sent']);
+
+                $this->assertTrue(
+                    $this->sender->send($this->shipmentMock)
+                );
+            } else {
+                $this->shipmentResourceMock->expects($this->once())
+                    ->method('saveAttribute')
+                    ->with($this->shipmentMock, 'send_email');
+
+                $this->assertFalse(
+                    $this->sender->send($this->shipmentMock)
+                );
+            }
+        } else {
+            $this->shipmentResourceMock->expects($this->once())
+                ->method('saveAttribute')
+                ->with($this->shipmentMock, 'send_email');
+
+            $this->assertFalse(
+                $this->sender->send($this->shipmentMock)
             );
-        $paymentInfoMock = $this->getMock(
-            '\Magento\Payment\Model\Info',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->orderMock->expects($this->once())
-            ->method('getPayment')
-            ->will($this->returnValue($paymentInfoMock));
-        $this->stepSendWithoutSendCopy();
-        $result = $this->sender->send($this->shipmentMock, true, $comment);
-        $this->assertTrue($result);
+        }
     }
 
-    public function testSendTrueWithoutCustomerCopy()
+    /**
+     * @return array
+     */
+    public function sendDataProvider()
     {
-        $billingAddress = $this->addressMock;
-        $comment = 'comment_test';
-
-        $this->orderMock->expects($this->once())
-            ->method('getCustomerIsGuest')
-            ->will($this->returnValue(false));
-        $this->stepAddressFormat($billingAddress);
-
-        $this->identityContainerMock->expects($this->once())
-            ->method('isEnabled')
-            ->will($this->returnValue(true));
-        $this->templateContainerMock->expects($this->once())
-            ->method('setTemplateVars')
-            ->with(
-                $this->equalTo(
-                    [
-                        'order' => $this->orderMock,
-                        'shipment' => $this->shipmentMock,
-                        'billing' => $billingAddress,
-                        'payment_html' => 'payment',
-                        'comment' => $comment,
-                        'store' => $this->storeMock,
-                        'formattedShippingAddress' => 1,
-                        'formattedBillingAddress' => 1
-                    ]
-                )
-            );
-        $this->stepSendWithCallSendCopyTo();
-        $result = $this->sender->send($this->shipmentMock, false, $comment);
-        $this->assertTrue($result);
+        return [
+            [0, 0, 1, true],
+            [0, 0, 0, true],
+            [0, 0, 1, false],
+            [0, 0, 0, false],
+            [0, 1, 1, true],
+            [0, 1, 0, true],
+            [1, null, null, null]
+        ];
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php
index d3a0a17afb3e01472852a13c96b1c486fe9f0572..b222a99d487454639b77b3a2552c45115a8f1919 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/OrderTest.php
@@ -348,6 +348,11 @@ class OrderTest extends \PHPUnit_Framework_TestCase
         $order->setData('state', $orderState);
         $payment = $this->_prepareOrderPayment($order);
         $canVoidOrder = true;
+
+        if ($orderState == \Magento\Sales\Model\Order::STATE_CANCELED) {
+            $canVoidOrder = false;
+        }
+
         if ($orderState == \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW) {
             $canVoidOrder = false;
         }
diff --git a/app/code/Magento/Sales/etc/adminhtml/system.xml b/app/code/Magento/Sales/etc/adminhtml/system.xml
index e7482704e39adc243e781283034f20f391152eb0..4ea65218f81382b54f65b88152199aa1e2866db6 100644
--- a/app/code/Magento/Sales/etc/adminhtml/system.xml
+++ b/app/code/Magento/Sales/etc/adminhtml/system.xml
@@ -119,6 +119,14 @@
             <label>Sales Emails</label>
             <tab>sales</tab>
             <resource>Magento_Sales::sales_email</resource>
+            <group id="general" type="text" sortOrder="0" showInDefault="1" showInWebsite="0" showInStore="0">
+                <label>General Settings</label>
+                <field id="async_sending" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
+                    <label>Asynchronous sending</label>
+                    <source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model>
+                    <backend_model>Magento\Sales\Model\Config\Backend\Email\AsyncSending</backend_model>
+                </field>
+            </group>
             <group id="order" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Order</label>
                 <field id="enabled" translate="label" type="select" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
@@ -340,7 +348,7 @@
             <label>PDF Print-outs</label>
             <tab>sales</tab>
             <resource>Magento_Sales::sales_pdf</resource>
-            <group id="invoice" translate="label" type="text" sortOrder="1" showInDefault="10" showInWebsite="1" showInStore="1">
+            <group id="invoice" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Invoice</label>
                 <field id="put_order_id" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Display Order ID in Header</label>
diff --git a/app/code/Magento/Sales/etc/config.xml b/app/code/Magento/Sales/etc/config.xml
index f88cf2955f60ed8f3db411ad7f4f49b37b87dc51..e786d5e45149b1b0cbb655d91a7cbc94ff33b5e0 100644
--- a/app/code/Magento/Sales/etc/config.xml
+++ b/app/code/Magento/Sales/etc/config.xml
@@ -23,6 +23,9 @@
             </minimum_order>
         </sales>
         <sales_email>
+            <general>
+                <async_sending>0</async_sending>
+            </general>
             <order>
                 <enabled>1</enabled>
                 <template>sales_email_order_template</template>
diff --git a/app/code/Magento/Sales/etc/crontab.xml b/app/code/Magento/Sales/etc/crontab.xml
index 1bd5b3e3e2478754784856b302a17ec3c2162470..15264798d8f1f8f34b800160472065b76f4ae72b 100644
--- a/app/code/Magento/Sales/etc/crontab.xml
+++ b/app/code/Magento/Sales/etc/crontab.xml
@@ -37,5 +37,17 @@
         <job name="sales_grid_order_creditmemo_async_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="asyncInsert">
             <schedule>*/1 * * * *</schedule>
         </job>
+        <job name="sales_send_order_emails" instance="Magento\Sales\Model\Observer\Order\SendEmails" method="execute">
+            <schedule>*/1 * * * *</schedule>
+        </job>
+        <job name="sales_send_order_invoice_emails" instance="Magento\Sales\Model\Observer\Order\Invoice\SendEmails" method="execute">
+            <schedule>*/1 * * * *</schedule>
+        </job>
+        <job name="sales_send_order_shipment_emails" instance="Magento\Sales\Model\Observer\Order\Shipment\SendEmails" method="execute">
+            <schedule>*/1 * * * *</schedule>
+        </job>
+        <job name="sales_send_order_creditmemo_emails" instance="Magento\Sales\Model\Observer\Order\Creditmemo\SendEmails" method="execute">
+            <schedule>*/1 * * * *</schedule>
+        </job>
     </group>
 </config>
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index ba45f06f9d73eed3c92d5d35faaaf5210363d158..9e20997c62f002c51ce2448f1e59e46acedf86da 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -157,6 +157,34 @@
             <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Creditmemo\Grid</argument>
         </arguments>
     </virtualType>
+    <virtualType name="Magento\Sales\Model\Observer\Order\SendEmails" type="Magento\Sales\Model\Observer\SendEmails">
+        <arguments>
+            <argument name="emailSender" xsi:type="object">Magento\Sales\Model\Order\Email\Sender\OrderSender</argument>
+            <argument name="entityResource" xsi:type="object">Magento\Sales\Model\Resource\Order</argument>
+            <argument name="entityCollection" xsi:type="object" shared="false">Magento\Sales\Model\Resource\Order\Collection</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Sales\Model\Observer\Order\Invoice\SendEmails" type="Magento\Sales\Model\Observer\SendEmails">
+        <arguments>
+            <argument name="emailSender" xsi:type="object">Magento\Sales\Model\Order\Email\Sender\InvoiceSender</argument>
+            <argument name="entityResource" xsi:type="object">Magento\Sales\Model\Resource\Order\Invoice</argument>
+            <argument name="entityCollection" xsi:type="object" shared="false">Magento\Sales\Model\Resource\Order\Invoice\Collection</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Sales\Model\Observer\Order\Shipment\SendEmails" type="Magento\Sales\Model\Observer\SendEmails">
+        <arguments>
+            <argument name="emailSender" xsi:type="object">Magento\Sales\Model\Order\Email\Sender\ShipmentSender</argument>
+            <argument name="entityResource" xsi:type="object">Magento\Sales\Model\Resource\Order\Shipment</argument>
+            <argument name="entityCollection" xsi:type="object" shared="false">Magento\Sales\Model\Resource\Order\Shipment\Collection</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Magento\Sales\Model\Observer\Order\Creditmemo\SendEmails" type="Magento\Sales\Model\Observer\SendEmails">
+        <arguments>
+            <argument name="emailSender" xsi:type="object">Magento\Sales\Model\Order\Email\Sender\CreditmemoSender</argument>
+            <argument name="entityResource" xsi:type="object">Magento\Sales\Model\Resource\Order\Creditmemo</argument>
+            <argument name="entityCollection" xsi:type="object" shared="false">Magento\Sales\Model\Resource\Order\Creditmemo\Collection</argument>
+        </arguments>
+    </virtualType>
     <type name="Magento\SalesSequence\Model\EntityPool">
         <arguments>
             <argument name="entities" xsi:type="array">
diff --git a/app/code/Magento/Sales/etc/events.xml b/app/code/Magento/Sales/etc/events.xml
index 1260e97f8d9d48c95b7e9e77102267339abefcc6..9e38abcd68e8c2812d99b3dc4f33c20135e9e2d5 100644
--- a/app/code/Magento/Sales/etc/events.xml
+++ b/app/code/Magento/Sales/etc/events.xml
@@ -39,6 +39,12 @@
         <observer name="sales_grid_order_shipment_async_insert" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="asyncInsert" />
         <observer name="sales_grid_order_creditmemo_async_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="asyncInsert" />
     </event>
+    <event name="config_data_sales_email_general_async_sending_disabled">
+        <observer name="sales_send_order_emails" instance="Magento\Sales\Model\Observer\Order\SendEmails" method="execute" />
+        <observer name="sales_send_order_invoice_emails" instance="Magento\Sales\Model\Observer\Order\Invoice\SendEmails" method="execute" />
+        <observer name="sales_send_order_shipment_emails" instance="Magento\Sales\Model\Observer\Order\Shipment\SendEmails" method="execute" />
+        <observer name="sales_send_order_creditmemo_emails" instance="Magento\Sales\Model\Observer\Order\Creditmemo\SendEmails" method="execute" />
+    </event>
     <event name="store_add">
         <observer name="magento_sequence" instance="Magento\SalesSequence\Model\Observer" method="execute" />
     </event>
diff --git a/app/code/Magento/Sales/etc/module.xml b/app/code/Magento/Sales/etc/module.xml
index eb894f667baef8cdb7b1214aec572f7660e00f50..931f2ab5884d8cb48936375b141eaba64c35d37e 100644
--- a/app/code/Magento/Sales/etc/module.xml
+++ b/app/code/Magento/Sales/etc/module.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_Sales" setup_version="2.0.3">
+    <module name="Magento_Sales" setup_version="2.0.4">
         <sequence>
             <module name="Magento_Rule"/>
             <module name="Magento_Catalog"/>
diff --git a/app/code/Magento/SalesRule/Setup/InstallSchema.php b/app/code/Magento/SalesRule/Setup/InstallSchema.php
index 700bdac3b587dd4fe706e90df90563a327d17cd8..0e319cccfc9fbd32dd184de60ba3bc3f37c1a8fa 100644
--- a/app/code/Magento/SalesRule/Setup/InstallSchema.php
+++ b/app/code/Magento/SalesRule/Setup/InstallSchema.php
@@ -264,7 +264,6 @@ class InstallSchema implements InstallSchemaInterface
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Salesrule Coupon'
@@ -302,14 +301,12 @@ class InstallSchema implements InstallSchemaInterface
             'coupon_id',
             $installer->getTable('salesrule_coupon'),
             'coupon_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_coupon_usage', 'customer_id', 'customer_entity', 'entity_id'),
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Salesrule Coupon Usage'
@@ -356,14 +353,12 @@ class InstallSchema implements InstallSchemaInterface
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_customer', 'rule_id', 'salesrule', 'rule_id'),
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Salesrule Customer'
@@ -415,14 +410,12 @@ class InstallSchema implements InstallSchemaInterface
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_label', 'store_id', 'store', 'store_id'),
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Salesrule Label'
@@ -472,8 +465,7 @@ class InstallSchema implements InstallSchemaInterface
             'attribute_id',
             $installer->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-            \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
                 'salesrule_product_attribute',
@@ -484,22 +476,19 @@ class InstallSchema implements InstallSchemaInterface
             'customer_group_id',
             $installer->getTable('customer_group'),
             'customer_group_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-            \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_product_attribute', 'rule_id', 'salesrule', 'rule_id'),
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-            \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_product_attribute', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
-            \Magento\Framework\DB\Ddl\Table::ACTION_NO_ACTION
+            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Salesrule Product Attribute'
         );
@@ -607,7 +596,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Coupon Aggregated'
@@ -705,7 +693,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Coupon Aggregated Order'
@@ -743,14 +730,12 @@ class InstallSchema implements InstallSchemaInterface
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('salesrule_website', 'website_id', 'core/website', 'website_id'),
             'website_id',
             $websitesTable,
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Rules To Websites Relations'
@@ -784,7 +769,6 @@ class InstallSchema implements InstallSchemaInterface
             'rule_id',
             $installer->getTable('salesrule'),
             'rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -796,7 +780,6 @@ class InstallSchema implements InstallSchemaInterface
             'customer_group_id',
             $customerGroupsTable,
             'customer_group_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Rules To Customer Groups Relations'
diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json
index 8d71564f7d997e9f8277565b9d07693caa49dfc4..da5dd3cbe32d26c5fd163586799d45cbe142642a 100644
--- a/app/code/Magento/SalesSequence/composer.json
+++ b/app/code/Magento/SalesSequence/composer.json
@@ -4,7 +4,7 @@
   "require": {
     "php": "~5.5.0|~5.6.0",
     "magento/framework": "0.74.0-beta4",
-    "magento/magento-composer-installer": "0.74.0-beta4"
+    "magento/magento-composer-installer": "*"
   },
   "type": "magento2-module",
   "version": "0.74.0-beta4",
diff --git a/app/code/Magento/Search/Setup/InstallSchema.php b/app/code/Magento/Search/Setup/InstallSchema.php
index 8a4acf9042b8ea7d17b9572e7536f8f3f20622d1..3c20f81310ed0b9ecc5c0bd6cbb08c82eafcce28 100644
--- a/app/code/Magento/Search/Setup/InstallSchema.php
+++ b/app/code/Magento/Search/Setup/InstallSchema.php
@@ -124,7 +124,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )
             ->setComment('Search query table');
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php
index 70310d404c6fa4273b42a117d9d705fd0fd2d9e2..c1fdc5ecd880d668a722046d05c0a3075e2b4540 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php
@@ -6,7 +6,7 @@
  */
 namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
 
-use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
+use Magento\Sales\Model\Order\Email\Sender\ShipmentCommentSender;
 use Magento\Backend\App\Action;
 use Magento\Framework\View\Result\LayoutFactory;
 
@@ -18,9 +18,9 @@ class AddComment extends \Magento\Backend\App\Action
     protected $shipmentLoader;
 
     /**
-     * @var ShipmentSender
+     * @var ShipmentCommentSender
      */
-    protected $shipmentSender;
+    protected $shipmentCommentSender;
 
     /**
      * @var LayoutFactory
@@ -30,17 +30,17 @@ class AddComment extends \Magento\Backend\App\Action
     /**
      * @param Action\Context $context
      * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
-     * @param ShipmentSender $shipmentSender
+     * @param ShipmentCommentSender $shipmentCommentSender
      * @param LayoutFactory $resultLayoutFactory
      */
     public function __construct(
         Action\Context $context,
         \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
-        ShipmentSender $shipmentSender,
+        ShipmentCommentSender $shipmentCommentSender,
         LayoutFactory $resultLayoutFactory
     ) {
         $this->shipmentLoader = $shipmentLoader;
-        $this->shipmentSender = $shipmentSender;
+        $this->shipmentCommentSender = $shipmentCommentSender;
         $this->resultLayoutFactory = $resultLayoutFactory;
         parent::__construct($context);
     }
@@ -79,7 +79,7 @@ class AddComment extends \Magento\Backend\App\Action
                 isset($data['is_visible_on_front'])
             );
 
-            $this->shipmentSender->send($shipment, !empty($data['is_customer_notified']), $data['comment']);
+            $this->shipmentCommentSender->send($shipment, !empty($data['is_customer_notified']), $data['comment']);
             $shipment->save();
             $resultLayout = $this->resultLayoutFactory->create();
             $resultLayout->addDefaultHandle();
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
index 7bb56f5087c0f345788b454326742b918893d245..c187d9bb21b55870757cb76449665f92a9718216 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -100,23 +100,19 @@ class Save extends \Magento\Backend\App\Action
                 return;
             }
 
-            $shipment->register();
-            $comment = '';
             if (!empty($data['comment_text'])) {
                 $shipment->addComment(
                     $data['comment_text'],
                     isset($data['comment_customer_notify']),
                     isset($data['is_visible_on_front'])
                 );
-                if (isset($data['comment_customer_notify'])) {
-                    $comment = $data['comment_text'];
-                }
-            }
 
-            if (!empty($data['send_email'])) {
-                $shipment->setEmailSent(true);
+                $shipment->setCustomerNote($data['comment_text']);
+                $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify']));
             }
 
+            $shipment->register();
+
             $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
             $responseAjax = new \Magento\Framework\Object();
             $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
@@ -128,7 +124,9 @@ class Save extends \Magento\Backend\App\Action
 
             $this->_saveShipment($shipment);
 
-            $this->shipmentSender->send($shipment, !empty($data['send_email']), $comment);
+            if (!empty($data['send_email'])) {
+                $this->shipmentSender->send($shipment);
+            }
 
             $shipmentCreatedMessage = __('The shipment has been created.');
             $labelCreatedMessage = __('You created the shipping label.');
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
index fd793ff3d03a7945feee7850449a192985b97485..04e8bc658ade10cc6a5f6d42ce34d7835710a5f4 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
@@ -8,10 +8,12 @@
 
 namespace Magento\Shipping\Model\Carrier;
 
-use Magento\Quote\Model\Quote\Address\AbstractCarrierInterface;
 use Magento\Quote\Model\Quote\Address\RateResult\Error;
 use Magento\Shipping\Model\Shipment\Request;
 
+/**
+ * Class AbstractCarrier
+ */
 abstract class AbstractCarrier extends \Magento\Framework\Object implements AbstractCarrierInterface
 {
     /**
@@ -137,6 +139,7 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
      * @param string $field
      * @return bool
      * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * @api
      */
     public function getConfigFlag($field)
     {
@@ -154,11 +157,11 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     /**
      * Collect and get rates
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return \Magento\Shipping\Model\Rate\Result|bool|null
      * @abstract
      */
-    abstract public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request);
+    abstract public function collectRates(\Magento\Framework\Object $request);
 
     /**
      * Do request to shipment
@@ -276,11 +279,11 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     }
 
     /**
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return $this|bool|false|\Magento\Framework\Model\AbstractModel
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
-    public function checkAvailableShipCountries(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function checkAvailableShipCountries(\Magento\Framework\Object $request)
     {
         $speCountriesAllow = $this->getConfigData('sallowspecific');
         /*
@@ -323,11 +326,11 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     /**
      * Processing additional validation to check is carrier applicable.
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
-     * @return $this|bool|Error
+     * @param \Magento\Framework\Object $request
+     * @return $this|bool|\Magento\Framework\Object
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function proccessAdditionalValidation(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function proccessAdditionalValidation(\Magento\Framework\Object $request)
     {
         return $this;
     }
@@ -593,6 +596,7 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
      *
      * @return bool
      * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     * @api
      */
     public function getDebugFlag()
     {
diff --git a/app/code/Magento/Quote/Model/Quote/Address/AbstractCarrierInterface.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierInterface.php
similarity index 83%
rename from app/code/Magento/Quote/Model/Quote/Address/AbstractCarrierInterface.php
rename to app/code/Magento/Shipping/Model/Carrier/AbstractCarrierInterface.php
index acc4f1b93d48291383afedf533b76438717bdaca..a8a9f2f747c31adfd37f69aae90489b571b69298 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/AbstractCarrierInterface.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierInterface.php
@@ -3,8 +3,11 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Quote\Model\Quote\Address;
+namespace Magento\Shipping\Model\Carrier;
 
+/**
+ * Interface AbstractCarrierInterface
+ */
 interface AbstractCarrierInterface
 {
     /**
@@ -12,16 +15,18 @@ interface AbstractCarrierInterface
      *
      * @param   string $field
      * @return  mixed
+     * @api
      */
     public function getConfigData($field);
 
     /**
      * Collect and get rates
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return \Magento\Framework\Object|bool|null
+     * @api
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request);
+    public function collectRates(\Magento\Framework\Object $request);
 
     /**
      * Do request to shipment
@@ -29,6 +34,7 @@ interface AbstractCarrierInterface
      *
      * @param \Magento\Framework\Object $request
      * @return \Magento\Framework\Object
+     * @api
      */
     public function requestToShipment($request);
 
@@ -38,6 +44,7 @@ interface AbstractCarrierInterface
      *
      * @param \Magento\Framework\Object $request
      * @return \Magento\Framework\Object
+     * @api
      */
     public function returnOfShipment($request);
 
@@ -46,6 +53,7 @@ interface AbstractCarrierInterface
      *
      * @param \Magento\Framework\Object|null $params
      * @return array
+     * @api
      */
     public function getContainerTypes(\Magento\Framework\Object $params = null);
 
@@ -53,6 +61,7 @@ interface AbstractCarrierInterface
      * Get Container Types, that could be customized
      *
      * @return array
+     * @api
      */
     public function getCustomizableContainerTypes();
 
@@ -61,27 +70,31 @@ interface AbstractCarrierInterface
      *
      * @param \Magento\Framework\Object|null $params
      * @return array
+     * @api
      */
     public function getDeliveryConfirmationTypes(\Magento\Framework\Object $params = null);
 
     /**
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return $this|bool|false|\Magento\Framework\Model\AbstractModel
+     * @api
      */
-    public function checkAvailableShipCountries(\Magento\Quote\Model\Quote\Address\RateRequest $request);
+    public function checkAvailableShipCountries(\Magento\Framework\Object $request);
 
     /**
      * Processing additional validation to check is carrier applicable.
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
-     * @return $this|\Magento\Quote\Model\Quote\Address\RateResult\Error|boolean
+     * @param \Magento\Framework\Object $request
+     * @return $this|\Magento\Framework\Object|boolean
+     * @api
      */
-    public function proccessAdditionalValidation(\Magento\Quote\Model\Quote\Address\RateRequest $request);
+    public function proccessAdditionalValidation(\Magento\Framework\Object $request);
 
     /**
      * Determine whether current carrier enabled for activity
      *
      * @return bool
+     * @api
      */
     public function isActive();
 
@@ -89,6 +102,7 @@ interface AbstractCarrierInterface
      * Whether this carrier has fixed rates calculation
      *
      * @return bool
+     * @api
      */
     public function isFixed();
 
@@ -96,6 +110,7 @@ interface AbstractCarrierInterface
      * Check if carrier has shipping tracking option available
      *
      * @return bool
+     * @api
      */
     public function isTrackingAvailable();
 
@@ -103,6 +118,7 @@ interface AbstractCarrierInterface
      * Check if carrier has shipping label option available
      *
      * @return bool
+     * @api
      */
     public function isShippingLabelsAvailable();
 
@@ -110,6 +126,7 @@ interface AbstractCarrierInterface
      *  Retrieve sort order of current carrier
      *
      * @return string|null
+     * @api
      */
     public function getSortOrder();
 
@@ -118,6 +135,7 @@ interface AbstractCarrierInterface
      *
      * @param float $cost
      * @return float final price for shipping method
+     * @api
      */
     public function getFinalPriceWithHandlingFee($cost);
 
@@ -126,6 +144,7 @@ interface AbstractCarrierInterface
      *
      * @param int $weight in someone measure
      * @return float Weight in pounds
+     * @api
      */
     public function convertWeightToLbs($weight);
 
@@ -134,6 +153,7 @@ interface AbstractCarrierInterface
      *
      * @param int|float $weight
      * @return int|float weight
+     * @api
      */
     public function getTotalNumOfBoxes($weight);
 
@@ -141,6 +161,7 @@ interface AbstractCarrierInterface
      * Is state province required
      *
      * @return bool
+     * @api
      */
     public function isStateProvinceRequired();
 
@@ -148,6 +169,7 @@ interface AbstractCarrierInterface
      * Check if city option required
      *
      * @return bool
+     * @api
      */
     public function isCityRequired();
 
@@ -156,6 +178,7 @@ interface AbstractCarrierInterface
      *
      * @param string|null $countryId
      * @return bool
+     * @api
      */
     public function isZipCodeRequired($countryId = null);
 
@@ -164,6 +187,7 @@ interface AbstractCarrierInterface
      *
      * @param mixed $debugData
      * @return void
+     * @api
      */
     public function debugData($debugData);
 
@@ -171,6 +195,7 @@ interface AbstractCarrierInterface
      * Getter for carrier code
      *
      * @return string
+     * @api
      */
     public function getCarrierCode();
 
@@ -179,6 +204,7 @@ interface AbstractCarrierInterface
      *
      * @param \Magento\Framework\Object $params
      * @return array
+     * @api
      */
     public function getContentTypes(\Magento\Framework\Object $params);
 }
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
index e4f38e73beec05dc3b6955429b04c0ffa6af97e8..99e544593f16bc73c2b191233afa2ffe99184657 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
@@ -157,6 +157,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      *
      * @param string $code
      * @return $this
+     * @api
      */
     public function setActiveFlag($code = 'active')
     {
@@ -179,6 +180,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      *
      * @param string $tracking
      * @return string|false
+     * @api
      */
     public function getTrackingInfo($tracking)
     {
@@ -249,6 +251,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      * @param RateRequest $request
      * @return array
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @api
      */
     public function getAllItems(RateRequest $request)
     {
@@ -279,12 +282,12 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     /**
      * Processing additional validation to check if carrier applicable.
      *
-     * @param RateRequest $request
-     * @return $this|bool|Error
+     * @param \Magento\Framework\Object $request
+     * @return $this|bool|\Magento\Framework\Object
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @SuppressWarnings(PHPMD.NPathComplexity)
      */
-    public function proccessAdditionalValidation(RateRequest $request)
+    public function proccessAdditionalValidation(\Magento\Framework\Object $request)
     {
         //Skip by item validation if there is no items in request
         if (!count($this->getAllItems($request))) {
@@ -523,6 +526,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      *
      * @todo implement rollback logic
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function rollBack($data)
     {
@@ -572,6 +576,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      * @param null|string $countyDest
      * @return bool
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @api
      */
     public function isGirthAllowed($countyDest = null)
     {
@@ -581,6 +586,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     /**
      * @param \Magento\Framework\Object|null $request
      * @return $this
+     * @api
      */
     public function setRawRequest($request)
     {
@@ -594,6 +600,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      * @param string $cost
      * @param string $method
      * @return float|string
+     * @api
      */
     public function getMethodPrice($cost, $method = '')
     {
@@ -615,6 +622,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      * @param string $customSimplexml
      *
      * @return \SimpleXMLElement|bool
+     * @api
      */
     public function parseXml($xmlContent, $customSimplexml = 'SimpleXMLElement')
     {
diff --git a/app/code/Magento/Shipping/Model/Carrier/CarrierInterface.php b/app/code/Magento/Shipping/Model/Carrier/CarrierInterface.php
index 980fe636356a5edcac7dc153e174085d21ac2c28..f422d20a9e3a3ed33ce3c5f560c1d4d57589d84a 100644
--- a/app/code/Magento/Shipping/Model/Carrier/CarrierInterface.php
+++ b/app/code/Magento/Shipping/Model/Carrier/CarrierInterface.php
@@ -11,6 +11,7 @@ interface CarrierInterface
      * Check if carrier has shipping tracking option available
      *
      * @return boolean
+     * @api
      */
     public function isTrackingAvailable();
 
@@ -18,6 +19,7 @@ interface CarrierInterface
      * Get allowed shipping methods
      *
      * @return array
+     * @api
      */
     public function getAllowedMethods();
 }
diff --git a/app/code/Magento/Shipping/Model/CarrierFactory.php b/app/code/Magento/Shipping/Model/CarrierFactory.php
index ac7dcc25146347f60e41e5e6696a02b171dc1c1a..699a7a3be09aa754363f208b337b5d3e416fa832 100644
--- a/app/code/Magento/Shipping/Model/CarrierFactory.php
+++ b/app/code/Magento/Shipping/Model/CarrierFactory.php
@@ -5,8 +5,9 @@
  */
 namespace Magento\Shipping\Model;
 
-use Magento\Quote\Model\Quote\Address\CarrierFactoryInterface;
-
+/**
+ * Class CarrierFactory
+ */
 class CarrierFactory implements CarrierFactoryInterface
 {
     /**
diff --git a/app/code/Magento/Quote/Model/Quote/Address/CarrierFactoryInterface.php b/app/code/Magento/Shipping/Model/CarrierFactoryInterface.php
similarity index 83%
rename from app/code/Magento/Quote/Model/Quote/Address/CarrierFactoryInterface.php
rename to app/code/Magento/Shipping/Model/CarrierFactoryInterface.php
index 9cd570db6feeccecbecad70df05a0ba2a58ab44e..2c0ac4c801d2f21ae0746930329689e5fb0f2e11 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/CarrierFactoryInterface.php
+++ b/app/code/Magento/Shipping/Model/CarrierFactoryInterface.php
@@ -3,8 +3,13 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Quote\Model\Quote\Address;
+namespace Magento\Shipping\Model;
 
+use Magento\Shipping\Model\Carrier\AbstractCarrierInterface;
+
+/**
+ * Interface CarrierFactoryInterface
+ */
 interface CarrierFactoryInterface
 {
     /**
@@ -12,6 +17,7 @@ interface CarrierFactoryInterface
      *
      * @param string $carrierCode
      * @return bool|AbstractCarrierInterface
+     * @api
      */
     public function get($carrierCode);
 
@@ -21,6 +27,7 @@ interface CarrierFactoryInterface
      * @param string $carrierCode
      * @param int|null $storeId
      * @return bool|AbstractCarrierInterface
+     * @api
      */
     public function create($carrierCode, $storeId = null);
 
@@ -29,6 +36,7 @@ interface CarrierFactoryInterface
      *
      * @param string $carrierCode
      * @return bool|AbstractCarrierInterface
+     * @api
      */
     public function getIfActive($carrierCode);
 
@@ -38,6 +46,7 @@ interface CarrierFactoryInterface
      * @param string $carrierCode
      * @param null|int $storeId
      * @return bool|AbstractCarrierInterface
+     * @api
      */
     public function createIfActive($carrierCode, $storeId = null);
 }
diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/AddCommentTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/AddCommentTest.php
index 4bc12ca36516585e31b7e146693ef2641dcbe5b7..6a60d69bdfe58eb6a6b84bb625f86082c9108820 100644
--- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/AddCommentTest.php
+++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/AddCommentTest.php
@@ -16,9 +16,9 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
     protected $shipmentLoaderMock;
 
     /**
-     * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentSender|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentCommentSender|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $shipmentSenderMock;
+    protected $shipmentCommentSenderMock;
 
     /**
      * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
@@ -69,8 +69,8 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->shipmentSenderMock = $this->getMock(
-            'Magento\Sales\Model\Order\Email\Sender\ShipmentSender',
+        $this->shipmentCommentSenderMock = $this->getMock(
+            'Magento\Sales\Model\Order\Email\Sender\ShipmentCommentSender',
             ['send', '__wakeup'],
             [],
             '',
@@ -139,7 +139,7 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
         $this->controller = new \Magento\Shipping\Controller\Adminhtml\Order\Shipment\AddComment(
             $contextMock,
             $this->shipmentLoaderMock,
-            $this->shipmentSenderMock,
+            $this->shipmentCommentSenderMock,
             $this->resultLayoutFactoryMock
         );
     }
@@ -210,7 +210,7 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
             ->method('load')
             ->will($this->returnValue($this->shipmentMock));
         $this->shipmentMock->expects($this->once())->method('addComment');
-        $this->shipmentSenderMock->expects($this->once())->method('send');
+        $this->shipmentCommentSenderMock->expects($this->once())->method('send');
         $this->shipmentMock->expects($this->once())->method('save');
         $layoutMock = $this->getMock('Magento\Framework\View\Layout', ['getBlock'], [], '', false);
         $blockMock = $this->getMock('Magento\Shipping\Block\Adminhtml\View\Comments', ['toHtml'], [], '', false);
@@ -318,7 +318,7 @@ class AddCommentTest extends \PHPUnit_Framework_TestCase
             ->method('load')
             ->will($this->returnValue($this->shipmentMock));
         $this->shipmentMock->expects($this->once())->method('addComment');
-        $this->shipmentSenderMock->expects($this->once())->method('send');
+        $this->shipmentCommentSenderMock->expects($this->once())->method('send');
         $this->shipmentMock->expects($this->once())->method('save')->will($this->throwException(new \Exception()));
         $this->exceptionResponse();
 
diff --git a/app/code/Magento/Shipping/etc/di.xml b/app/code/Magento/Shipping/etc/di.xml
index 92fad82f65d25fb31c36ebc8f3de56a5b3abb8d7..9b785dac596f1f2a0bf2addc690fa8ca8cec1799 100644
--- a/app/code/Magento/Shipping/etc/di.xml
+++ b/app/code/Magento/Shipping/etc/di.xml
@@ -7,6 +7,6 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
     <preference for="Magento\Quote\Model\Quote\Address\RateCollectorInterface" type="Magento\Shipping\Model\Shipping" />
-    <preference for="Magento\Quote\Model\Quote\Address\CarrierFactoryInterface" type="Magento\Shipping\Model\CarrierFactory" />
+    <preference for="Magento\Shipping\Model\CarrierFactoryInterface" type="Magento\Shipping\Model\CarrierFactory" />
     <preference for="Magento\Shipping\Model\Carrier\Source\GenericInterface" type="\Magento\Shipping\Model\Carrier\Source\GenericDefault" />
 </config>
diff --git a/app/code/Magento/Sitemap/Setup/InstallSchema.php b/app/code/Magento/Sitemap/Setup/InstallSchema.php
index 202d222ec8ff8e06d4ece30cc339308959836f52..bca997246b74da37d27c3a02b1d842b71f37a7a9 100644
--- a/app/code/Magento/Sitemap/Setup/InstallSchema.php
+++ b/app/code/Magento/Sitemap/Setup/InstallSchema.php
@@ -73,7 +73,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'XML Sitemap'
diff --git a/app/code/Magento/Store/Setup/InstallSchema.php b/app/code/Magento/Store/Setup/InstallSchema.php
index f76cc884777a8f1165ae5a6dbbcf61cac9124d4d..948659c8c34228615d5fff9fef35276b9f806984 100644
--- a/app/code/Magento/Store/Setup/InstallSchema.php
+++ b/app/code/Magento/Store/Setup/InstallSchema.php
@@ -133,7 +133,6 @@ class InstallSchema implements InstallSchemaInterface
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            Table::ACTION_CASCADE,
             Table::ACTION_CASCADE
         )->setComment(
             'Store Groups'
@@ -209,14 +208,12 @@ class InstallSchema implements InstallSchemaInterface
             'group_id',
             $installer->getTable('store_group'),
             'group_id',
-            Table::ACTION_CASCADE,
             Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('store', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $installer->getTable('store_website'),
             'website_id',
-            Table::ACTION_CASCADE,
             Table::ACTION_CASCADE
         )->setComment(
             'Stores'
diff --git a/app/code/Magento/Tax/Setup/InstallSchema.php b/app/code/Magento/Tax/Setup/InstallSchema.php
index 85218d2195b724907b3cc59c0ac0b10612f3904c..6d708d5862f56f6560bbc0a8515d9ccfd9f99a77 100644
--- a/app/code/Magento/Tax/Setup/InstallSchema.php
+++ b/app/code/Magento/Tax/Setup/InstallSchema.php
@@ -228,14 +228,12 @@ class InstallSchema implements InstallSchemaInterface
             'product_tax_class_id',
             $setup->getTable('tax_class'),
             'class_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('tax_calculation', 'customer_tax_class_id', 'tax_class', 'class_id'),
             'customer_tax_class_id',
             $setup->getTable('tax_class'),
             'class_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName(
@@ -247,7 +245,6 @@ class InstallSchema implements InstallSchemaInterface
             'tax_calculation_rate_id',
             $setup->getTable('tax_calculation_rate'),
             'tax_calculation_rate_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName(
@@ -259,7 +256,6 @@ class InstallSchema implements InstallSchemaInterface
             'tax_calculation_rule_id',
             $setup->getTable('tax_calculation_rule'),
             'tax_calculation_rule_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Tax Calculation'
@@ -306,7 +302,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $setup->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName(
@@ -318,7 +313,6 @@ class InstallSchema implements InstallSchemaInterface
             'tax_calculation_rate_id',
             $setup->getTable('tax_calculation_rate'),
             'tax_calculation_rate_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Tax Calculation Rate Title'
@@ -394,7 +388,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $setup->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Tax Order Aggregation'
@@ -492,21 +485,18 @@ class InstallSchema implements InstallSchemaInterface
             'associated_item_id',
             $setup->getTable('sales_order_item'),
             'item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('sales_order_tax_item', 'tax_id', 'sales_order_tax', 'tax_id'),
             'tax_id',
             $setup->getTable('sales_order_tax'),
             'tax_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('sales_order_tax_item', 'item_id', 'sales_order_item', 'item_id'),
             'item_id',
             $setup->getTable('sales_order_item'),
             'item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Sales Order Tax Item'
diff --git a/app/code/Magento/Theme/Setup/InstallSchema.php b/app/code/Magento/Theme/Setup/InstallSchema.php
index f2135e0c1e4df8f03743be922c9e3aafe05026d5..b7f6d0edb3775a0f668233ab6bf758beea3ff807 100644
--- a/app/code/Magento/Theme/Setup/InstallSchema.php
+++ b/app/code/Magento/Theme/Setup/InstallSchema.php
@@ -150,7 +150,6 @@ class InstallSchema implements InstallSchemaInterface
             'theme_id',
             $installer->getTable('theme'),
             'theme_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Core theme files'
@@ -200,7 +199,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Design Changes'
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Favicon/FaviconTest.php b/app/code/Magento/Theme/Test/Unit/Model/Favicon/FaviconTest.php
index cb439cd4ea692ffe840a80d5434b9e683c132169..d8ee45c4f15f067f6744c7c93071470040539b1f 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Favicon/FaviconTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Favicon/FaviconTest.php
@@ -85,7 +85,7 @@ class FaviconTest extends \PHPUnit_Framework_TestCase
     public function testGetFaviconFile()
     {
         $scopeConfigValue = 'path';
-        $urlToMediaDir = 'http://magneto.url/pub/media/';
+        $urlToMediaDir = 'http://magento.url/pub/media/';
         $expectedFile = ImageFavicon::UPLOAD_DIR . '/' . $scopeConfigValue;
         $expectedUrl = $urlToMediaDir . $expectedFile;
 
diff --git a/app/code/Magento/Translation/Setup/InstallSchema.php b/app/code/Magento/Translation/Setup/InstallSchema.php
index a7d4df05902bc0c50d9c3854fd40e503abe1a090..24afcc20396939c02e7360d551364a7ff521c879 100644
--- a/app/code/Magento/Translation/Setup/InstallSchema.php
+++ b/app/code/Magento/Translation/Setup/InstallSchema.php
@@ -96,7 +96,6 @@ class InstallSchema implements InstallSchemaInterface
                 'store_id',
                 $installer->getTable('store'),
                 'store_id',
-                \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
                 \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
             )->setComment('Translations');
         $installer->getConnection()->createTable($table);
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index e88b68ea433cafc08dba11c7c4dbec7547c6aaf8..3085a8b35c988766d5d48820d5727fc498c1bf65 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -184,10 +184,10 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     /**
      * Collect and get rates
      *
-     * @param RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return Result|bool|null
      */
-    public function collectRates(RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag($this->_activeFlag)) {
             return false;
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index 49976c39fef46b183e6fd46190f5a28edfd11336..2d7845696c840f6695756459fa162e9c1832b5b5 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -177,10 +177,10 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * Collect and get rates
      *
-     * @param \Magento\Quote\Model\Quote\Address\RateRequest $request
+     * @param \Magento\Framework\Object $request
      * @return Result|bool|null
      */
-    public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $request)
+    public function collectRates(\Magento\Framework\Object $request)
     {
         if (!$this->getConfigFlag($this->_activeFlag)) {
             return false;
diff --git a/app/code/Magento/Variable/Setup/InstallSchema.php b/app/code/Magento/Variable/Setup/InstallSchema.php
index b2af66d257b7c3df5099a247c97239de561ed245..043ccaad3360d650fcaa4507c0699c9595d646cb 100644
--- a/app/code/Magento/Variable/Setup/InstallSchema.php
+++ b/app/code/Magento/Variable/Setup/InstallSchema.php
@@ -17,6 +17,7 @@ class InstallSchema implements InstallSchemaInterface
 {
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
     public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
     {
@@ -135,7 +136,6 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         );
         $connection->addForeignKey(
@@ -144,12 +144,9 @@ class InstallSchema implements InstallSchemaInterface
             'variable_id',
             $installer->getTable('variable'),
             'variable_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         );
 
         $installer->endSetup();
-
     }
-
 }
diff --git a/app/code/Magento/Weee/Setup/InstallSchema.php b/app/code/Magento/Weee/Setup/InstallSchema.php
index c304dd40f5a099ea51e588c7fd3c35fca3adb148..6c098098c409cd434c84066bb8fdbb861a210012 100644
--- a/app/code/Magento/Weee/Setup/InstallSchema.php
+++ b/app/code/Magento/Weee/Setup/InstallSchema.php
@@ -86,28 +86,24 @@ class InstallSchema implements InstallSchemaInterface
             'country',
             $setup->getTable('directory_country'),
             'country_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('weee_tax', 'entity_id', 'catalog_product_entity', 'entity_id'),
             'entity_id',
             $setup->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('weee_tax', 'website_id', 'store_website', 'website_id'),
             'website_id',
             $setup->getTable('store_website'),
             'website_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $setup->getFkName('weee_tax', 'attribute_id', 'eav_attribute', 'attribute_id'),
             'attribute_id',
             $setup->getTable('eav_attribute'),
             'attribute_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Weee Tax'
diff --git a/app/code/Magento/Widget/Setup/InstallSchema.php b/app/code/Magento/Widget/Setup/InstallSchema.php
index 4d71df5ef6ca67596d40ec2228ec75ca5f1d3966..60a95b70f7b5c931436a7fe6bd81e554bd6e3b62 100644
--- a/app/code/Magento/Widget/Setup/InstallSchema.php
+++ b/app/code/Magento/Widget/Setup/InstallSchema.php
@@ -167,7 +167,6 @@ class InstallSchema implements InstallSchemaInterface
             'theme_id',
             $installer->getTable('theme'),
             'theme_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Instances of Widget for Package Theme'
@@ -235,7 +234,6 @@ class InstallSchema implements InstallSchemaInterface
             'instance_id',
             $installer->getTable('widget_instance'),
             'instance_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Instance of Widget on Page'
@@ -275,7 +273,6 @@ class InstallSchema implements InstallSchemaInterface
             'page_id',
             $installer->getTable('widget_instance_page'),
             'page_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName(
@@ -287,7 +284,6 @@ class InstallSchema implements InstallSchemaInterface
             'layout_update_id',
             $installer->getTable('layout_update'),
             'layout_update_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Layout updates'
@@ -380,7 +376,6 @@ class InstallSchema implements InstallSchemaInterface
             'layout_update_id',
             $installer->getTable('layout_update'),
             'layout_update_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addIndex(
             $installer->getIdxName(
@@ -394,14 +389,12 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addForeignKey(
             $installer->getFkName('layout_link', 'theme_id', 'theme', 'theme_id'),
             'theme_id',
             $installer->getTable('theme'),
             'theme_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Layout Link'
diff --git a/app/code/Magento/Wishlist/Setup/InstallSchema.php b/app/code/Magento/Wishlist/Setup/InstallSchema.php
index cde21e7ff48653f2f09dbe0a05429befc21ce0f8..f2894e5fbec2ea9c8218117e9112f810a8562b0b 100644
--- a/app/code/Magento/Wishlist/Setup/InstallSchema.php
+++ b/app/code/Magento/Wishlist/Setup/InstallSchema.php
@@ -76,7 +76,6 @@ class InstallSchema implements InstallSchemaInterface
             'customer_id',
             $installer->getTable('customer_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Wishlist main Table'
@@ -138,7 +137,6 @@ class InstallSchema implements InstallSchemaInterface
             'wishlist_id',
             $installer->getTable('wishlist'),
             'wishlist_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addIndex(
             $installer->getIdxName('wishlist_item', 'product_id'),
@@ -148,7 +146,6 @@ class InstallSchema implements InstallSchemaInterface
             'product_id',
             $installer->getTable('catalog_product_entity'),
             'entity_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->addIndex(
             $installer->getIdxName('wishlist_item', 'store_id'),
@@ -158,8 +155,7 @@ class InstallSchema implements InstallSchemaInterface
             'store_id',
             $installer->getTable('store'),
             'store_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL,
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
+            \Magento\Framework\DB\Ddl\Table::ACTION_SET_NULL
         )->setComment(
             'Wishlist items'
         );
@@ -205,7 +201,6 @@ class InstallSchema implements InstallSchemaInterface
             'wishlist_item_id',
             $installer->getTable('wishlist_item'),
             'wishlist_item_id',
-            \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE,
             \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
         )->setComment(
             'Wishlist Item Option Table'
diff --git a/bin/magento b/bin/magento
old mode 100644
new mode 100755
diff --git a/composer.json b/composer.json
index c8721c87609c6a84b5b35d2abd2e15b2f0fddbdb..907d23ff711529e697064e42d0eab2a6c2465669 100644
--- a/composer.json
+++ b/composer.json
@@ -63,6 +63,7 @@
         "magento/module-backend": "self.version",
         "magento/module-backup": "self.version",
         "magento/module-bundle": "self.version",
+        "magento/module-cache-invalidate": "self.version",
         "magento/module-captcha": "self.version",
         "magento/module-catalog": "self.version",
         "magento/module-catalog-import-export": "self.version",
diff --git a/composer.lock b/composer.lock
index 02e531e791e517c23da1202be3be61491553ec1d..1850375542413cf443c72fd68f36fd6fe6b21d7f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "974fa7d59a25f8a31c70ea53068944cd",
+    "hash": "35d05640e3dc260b7a5b09310611194a",
     "packages": [
         {
             "name": "composer/composer",
@@ -2007,16 +2007,16 @@
         },
         {
             "name": "fabpot/php-cs-fixer",
-            "version": "v1.6.1",
+            "version": "v1.6.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-                "reference": "14f802b2c00b672676d55612e3c0d03465b69bf6"
+                "reference": "a574ba148953fea1f78428d4b7c6843e759711f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/14f802b2c00b672676d55612e3c0d03465b69bf6",
-                "reference": "14f802b2c00b672676d55612e3c0d03465b69bf6",
+                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/a574ba148953fea1f78428d4b7c6843e759711f3",
+                "reference": "a574ba148953fea1f78428d4b7c6843e759711f3",
                 "shasum": ""
             },
             "require": {
@@ -2056,7 +2056,7 @@
                 }
             ],
             "description": "A script to automatically fix Symfony Coding Standard",
-            "time": "2015-04-09 19:10:26"
+            "time": "2015-04-13 21:33:33"
         },
         {
             "name": "league/climate",
@@ -2272,16 +2272,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.0.15",
+            "version": "2.0.16",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
+                "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
-                "reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/934fd03eb6840508231a7f73eb8940cf32c3b66c",
+                "reference": "934fd03eb6840508231a7f73eb8940cf32c3b66c",
                 "shasum": ""
             },
             "require": {
@@ -2330,7 +2330,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2015-01-24 10:06:35"
+            "time": "2015-04-11 04:35:00"
         },
         {
             "name": "phpunit/php-file-iterator",
diff --git a/dev/tests/api-functional/config/install-config-mysql.php.dist b/dev/tests/api-functional/config/install-config-mysql.php.dist
index 96949ee5bf8ab889adceb33e4a1d353e73dc3dac..535cfb7232e8f1ef2a58a98916fe49b98bea5d6a 100644
--- a/dev/tests/api-functional/config/install-config-mysql.php.dist
+++ b/dev/tests/api-functional/config/install-config-mysql.php.dist
@@ -12,7 +12,7 @@ return [
     'db_host'                      => 'localhost',
     'db_name'                      => 'magento_functional_tests',
     'db_user'                      => 'root',
-    'db_pass'                      => '',
+    'db_password'                  => '',
     'backend_frontname'            => 'backend',
     'base_url'                     => 'http://localhost/',
     'use_secure'                   => '0',
@@ -20,7 +20,7 @@ return [
     'admin_lastname'               => 'Admin',
     'admin_firstname'              => 'Admin',
     'admin_email'                  => 'admin@example.com',
-    'admin_username'               => 'admin',
+    'admin_user'                   => 'admin',
     'admin_password'               => '123123q',
     'admin_use_security_key'       => '0',
     /* PayPal has limitation for order number - 20 characters. 10 digits prefix + 8 digits number is good enough */
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
index 0695e5fbe7dd5b3dc5349d9bd9fc029cbec26229..56936fa716784c7ea003afd93e87ab31da048817 100644
--- a/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
@@ -33,7 +33,7 @@ class WebApiApplication extends Application
 
         /* Install application */
         if ($installOptions) {
-            $installCmd = 'php -f ' . BP . '/setup/index.php install';
+            $installCmd = 'php -f ' . BP . '/bin/magento setup:install';
             $installArgs = [];
             foreach ($installOptions as $optionName => $optionValue) {
                 if (is_bool($optionValue)) {
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
index 74ec107e09a60690f1292e847fbc0a5c289f41b0..fbfb262f1206d798a750dcfede4c913b96eed3c5 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
@@ -90,7 +90,7 @@ class InstallTest extends Injectable
     {
         $magentoBaseDir = dirname(dirname(dirname(MTF_BP)));
         // Uninstall Magento.
-        shell_exec("php -f $magentoBaseDir/setup/index.php uninstall");
+        shell_exec("php -f $magentoBaseDir/bin/magento setup:uninstall -n");
         $this->installPage = $installPage;
         $this->homePage = $homePage;
     }
diff --git a/dev/tests/integration/etc/install-config-mysql.php.dist b/dev/tests/integration/etc/install-config-mysql.php.dist
index 391e1a7679b00c152b165b379be8bd5d9ea508bb..0d8fb591eb14454b4d3c46045e3606ab6e47dea3 100644
--- a/dev/tests/integration/etc/install-config-mysql.php.dist
+++ b/dev/tests/integration/etc/install-config-mysql.php.dist
@@ -7,11 +7,11 @@
 return [
     'db_host' => 'localhost',
     'db_user' => 'root',
-    'db_pass' => '',
+    'db_password' => '',
     'db_name' => 'magento_integration_tests',
     'db_prefix' => '',
     'backend_frontname' => 'backend',
-    'admin_username' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
+    'admin_user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
     'admin_password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
     'admin_email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
     'admin_firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
diff --git a/dev/tests/integration/etc/install-config-mysql.travis.php.dist b/dev/tests/integration/etc/install-config-mysql.travis.php.dist
index e91586f30315cc3503c109520869dfca388ac02d..a0e25fd80384beb21201843bca7e59a435a26c34 100644
--- a/dev/tests/integration/etc/install-config-mysql.travis.php.dist
+++ b/dev/tests/integration/etc/install-config-mysql.travis.php.dist
@@ -7,11 +7,11 @@
 return [
     'db_host' => '127.0.0.1',
     'db_user' => 'travis',
-    'db_pass' => '',
+    'db_password' => '',
     'db_name' => 'magento_integration_tests',
     'db_prefix' => 'travis_',
     'backend_frontname' => 'backend',
-    'admin_username' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
+    'admin_user' => \Magento\TestFramework\Bootstrap::ADMIN_NAME,
     'admin_password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
     'admin_email' => \Magento\TestFramework\Bootstrap::ADMIN_EMAIL,
     'admin_firstname' => \Magento\TestFramework\Bootstrap::ADMIN_FIRSTNAME,
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index 385e1a76b951607ec52a9ce1f6a8e383c2ae7952..d8aee09eb186a8a531ec1fb6f49790fc770d038d 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -174,7 +174,7 @@ class Application
                 $installConfig = $this->getInstallConfig();
                 $host = $installConfig['db_host'];
                 $user = $installConfig['db_user'];
-                $password = $installConfig['db_pass'];
+                $password = $installConfig['db_password'];
                 $dbName = $installConfig['db_name'];
             }
             $this->_db = new Db\Mysql(
@@ -371,12 +371,16 @@ class Application
      */
     public function cleanup()
     {
+        $this->_ensureDirExists($this->installDir);
+        $this->_ensureDirExists($this->_configDir);
+
+        $this->copyAppConfigFiles();
         /**
          * @see \Magento\Setup\Mvc\Bootstrap\InitParamListener::BOOTSTRAP_PARAM
          */
         $this->_shell->execute(
-            'php -f %s uninstall --magento_init_params=%s',
-            [BP . '/setup/index.php', $this->getInitParamsQuery()]
+            'php -f %s setup:uninstall -n --magento_init_params=%s',
+            [BP . '/bin/magento', $this->getInitParamsQuery()]
         );
     }
 
@@ -407,8 +411,8 @@ class Application
 
         // run install script
         $this->_shell->execute(
-            'php -f %s install ' . implode(' ', array_keys($installParams)),
-            array_merge([BP . '/setup/index.php'], array_values($installParams))
+            'php -f %s setup:install ' . implode(' ', array_keys($installParams)),
+            array_merge([BP . '/bin/magento'], array_values($installParams))
         );
 
         // enable only specified list of caches
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ObjectManager/Configurator.php b/dev/tests/integration/framework/Magento/TestFramework/ObjectManager/Configurator.php
index 24f9e0bf8799f6f3e9e7a92eef545625cddf847a..c236ee4aa214ca8bf07112c729277d7aedd2f0db 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ObjectManager/Configurator.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ObjectManager/Configurator.php
@@ -16,7 +16,6 @@ class Configurator implements \Magento\Framework\ObjectManager\DynamicConfigInte
     {
         return [
             'preferences' => [
-                'Magento\Framework\Stdlib\Cookie' => 'Magento\TestFramework\Cookie',
                 'Magento\Framework\Stdlib\CookieManagerInterface' => 'Magento\TestFramework\CookieManager',
             ]
         ];
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ObjectManagerFactory.php b/dev/tests/integration/framework/Magento/TestFramework/ObjectManagerFactory.php
index 8cebbc8f76dfcfe7677bb0c52a03950f3bdf9cac..e499e0d929ae159842558b2b45a4ece21bde8438 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ObjectManagerFactory.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ObjectManagerFactory.php
@@ -95,7 +95,6 @@ class ObjectManagerFactory extends \Magento\Framework\App\ObjectManagerFactory
                     'Magento\Framework\Stdlib\CookieManagerInterface' => 'Magento\TestFramework\CookieManager',
                     'Magento\Framework\ObjectManager\DynamicConfigInterface' =>
                         '\Magento\TestFramework\ObjectManager\Configurator',
-                    'Magento\Framework\Stdlib\Cookie' => 'Magento\TestFramework\Cookie',
                     'Magento\Framework\App\RequestInterface' => 'Magento\TestFramework\Request',
                     'Magento\Framework\App\Request\Http' => 'Magento\TestFramework\Request',
                     'Magento\Framework\App\ResponseInterface' => 'Magento\TestFramework\Response',
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
index e9d78a0385a79b2f798f4fbb21ad8fc7b0881520..3591424ed146ec0e576106d5cd9bbb1203ffb7c2 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
@@ -15,7 +15,7 @@ class DbStatusValidatorTest extends \Magento\TestFramework\TestCase\AbstractCont
     /**
      * @magentoDbIsolation enabled
      * @expectedException \Magento\Framework\Exception\LocalizedException
-     * @expectedExceptionMessage Please update your database
+     * @expectedExceptionMessage Please upgrade your database
      */
     public function testValidationOutdatedDb()
     {
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/QuoteTest.php
deleted file mode 100644
index 7b3f1e37c8db98dd810ec1553d1033b9159022dd..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/QuoteTest.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Sales\Model\Resource;
-
-class QuoteTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Quote\Model\Resource\Quote
-     */
-    protected $_resourceModel;
-
-    protected function setUp()
-    {
-        $this->_resourceModel = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Quote\Model\Resource\Quote'
-        );
-    }
-
-    /**
-     * @magentoDataFixture Magento/Sales/_files/order.php
-     */
-    public function testIsOrderIncrementIdUsedNumericIncrementId()
-    {
-        $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('100000001'));
-    }
-
-    /**
-     * @magentoDataFixture Magento/Sales/_files/order_alphanumeric_id.php
-     */
-    public function testIsOrderIncrementIdUsedAlphanumericIncrementId()
-    {
-        $this->assertTrue($this->_resourceModel->isOrderIncrementIdUsed('M00000001'));
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php
index 1862adfcee81f7a0d9a509e88b0d51b9febd2b05..c476e27898e83aa6c0632abe182c97d668349729 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php
@@ -48,7 +48,7 @@ $quote->setCustomerIsGuest(
         'Magento\Store\Model\StoreManagerInterface'
     )->getStore()->getId()
 )->setReservedOrderId(
-    'test01'
+    '100000001'
 )->setBillingAddress(
     $billingAddress
 )->setShippingAddress(
diff --git a/dev/tests/performance/config.php.dist b/dev/tests/performance/config.php.dist
index 64c8f2f5c2ec30e6160500dc4b3a65d63b750ca3..e145b9768ffe2d8b6178edc2e718e0c8220d0770 100644
--- a/dev/tests/performance/config.php.dist
+++ b/dev/tests/performance/config.php.dist
@@ -16,14 +16,14 @@ return array(
                 'db_host'                    => 'localhost',
                 'db_name'                    => 'magento',
                 'db_user'                    => 'root',
-                'db_pass'                    => '',
+                'db_password'                => '',
                 'use_secure'                 => '0',
                 'use_secure_admin'           => '0',
                 'use_rewrites'               => '0',
                 'admin_lastname'             => 'Admin',
                 'admin_firstname'            => 'Admin',
                 'admin_email'                => 'admin@example.com',
-                'admin_username'             => 'admin',
+                'admin_user'                 => 'admin',
                 'admin_password'             => '123123q',
                 'admin_use_security_key'     => '0',
                 'backend_frontname'          => 'backend',
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Application.php b/dev/tests/performance/framework/Magento/TestFramework/Application.php
index d3728db16b2fb43d6959c29772b3104c7a5d4647..d236858ef259a39473edec5fc8df71fdae81d41a 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Application.php
@@ -63,9 +63,9 @@ class Application
         \Magento\Framework\ObjectManagerInterface $objectManager,
         \Magento\Framework\Shell $shell
     ) {
-        $shellDir = $config->getApplicationBaseDir() . '/setup';
+        $shellDir = $config->getApplicationBaseDir() . '/bin';
         $this->_objectManager = $objectManager;
-        $this->_script = $this->_assertPath($shellDir . '/index.php');
+        $this->_script = $this->_assertPath($shellDir . '/magento');
         $this->_config = $config;
         $this->_shell = $shell;
     }
@@ -130,7 +130,7 @@ class Application
      */
     protected function _uninstall()
     {
-        $this->_shell->execute('php -f %s uninstall', [$this->_script]);
+        $this->_shell->execute('php -f %s setup:uninstall -n', [$this->_script]);
 
         $this->_isInstalled = false;
         $this->_fixtures = [];
@@ -157,7 +157,7 @@ class Application
         // Populate install options with global options
         $baseUrl = 'http://' . $this->_config->getApplicationUrlHost() . $this->_config->getApplicationUrlPath();
         $installOptions = array_merge($installOptions, ['base_url' => $baseUrl, 'base_url_secure' => $baseUrl]);
-        $installCmd = 'php -f %s install';
+        $installCmd = 'php -f %s setup:install';
         $installCmdArgs = [$this->_script];
         foreach ($installOptions as $optionName => $optionValue) {
             $installCmd .= " --{$optionName}=%s";
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php b/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
index f0a6f141fad07c67e1da25ee39666e4c0bcc44da..bd01b881c6bb9bb427690147be710d7a21a1900f 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Performance/Config.php
@@ -117,7 +117,7 @@ class Config
         }
 
         // Validate admin options data
-        $requiredAdminKeys = ['admin_username', 'admin_password', 'backend_frontname'];
+        $requiredAdminKeys = ['admin_user', 'admin_password', 'backend_frontname'];
         foreach ($requiredAdminKeys as $requiredKeyName) {
             if (empty($configData['application']['installation']['options'][$requiredKeyName])) {
                 throw new \Magento\Framework\Exception\LocalizedException(
@@ -278,7 +278,7 @@ class Config
             \Magento\TestFramework\Performance\Scenario::ARG_PATH => $this->getApplicationUrlPath(),
             \Magento\TestFramework\Performance\Scenario::ARG_BASEDIR => $this->getApplicationBaseDir(),
             \Magento\TestFramework\Performance\Scenario::ARG_BACKEND_FRONTNAME => $options['backend_frontname'],
-            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USERNAME => $options['admin_username'],
+            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USER => $options['admin_user'],
             \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_PASSWORD => $options['admin_password'],
             'jmeter.save.saveservice.output_format' => 'xml',
         ];
diff --git a/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php b/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
index 8de697f07f641922b5c676589db8b1d6e754defd..ab19c64f5aebea70028fa971cd2b2c8a96995ee8 100644
--- a/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
+++ b/dev/tests/performance/framework/Magento/TestFramework/Performance/Scenario.php
@@ -24,7 +24,7 @@ class Scenario
 
     const ARG_BASEDIR = 'basedir';
 
-    const ARG_ADMIN_USERNAME = 'admin_username';
+    const ARG_ADMIN_USER = 'admin_user';
 
     const ARG_ADMIN_PASSWORD = 'admin_password';
 
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
index f6598461c8823a3e7bc721677b0532bb6c426471..1ae2bf1fbe1424a68c21aa0449f40fed380ebee7 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/ApplicationTest.php
@@ -49,7 +49,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
         $this->_fixtureDir = __DIR__ . '/Performance/_files';
         $this->_fixtureConfigData = require $this->_fixtureDir . '/config_data.php';
 
-        $this->_script = realpath($this->_fixtureDir . '/app_base_dir/setup/index.php');
+        $this->_script = realpath($this->_fixtureDir . '/app_base_dir/bin/magento');
 
         $this->_config = new \Magento\TestFramework\Performance\Config(
             $this->_fixtureConfigData,
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
index 7b2513aa5756a363d5c01953e33d2614a6829735..39685b58894125220e63fd532b39f5b0f54282ac 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/ConfigTest.php
@@ -145,7 +145,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             'option1' => 'value 1',
             'option2' => 'value 2',
             'backend_frontname' => 'backend',
-            'admin_username' => 'admin',
+            'admin_user' => 'admin',
             'admin_password' => 'password1',
         ];
         $this->assertEquals($expectedOptions, $this->_object->getInstallOptions());
@@ -174,7 +174,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             \Magento\TestFramework\Performance\Scenario::ARG_HOST => '127.0.0.1',
             \Magento\TestFramework\Performance\Scenario::ARG_PATH => '/',
             \Magento\TestFramework\Performance\Scenario::ARG_BACKEND_FRONTNAME => 'backend',
-            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USERNAME => 'admin',
+            \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_USER => 'admin',
             \Magento\TestFramework\Performance\Scenario::ARG_ADMIN_PASSWORD => 'password1',
             \Magento\TestFramework\Performance\Scenario::ARG_BASEDIR => $this->_getFixtureAppBaseDir(),
             'arg1' => 'value 1',
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/setup/index.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/bin/magento
old mode 100644
new mode 100755
similarity index 63%
rename from dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/setup/index.php
rename to dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/bin/magento
index 05d5a3da741d1b858cb44e560f8d7943b3a37b61..977e41071374b98a96f51beca2295bccb6257f31
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/setup/index.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/app_base_dir/bin/magento
@@ -1,7 +1,6 @@
+#!/usr/bin/env php
 <?php
 /**
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
- */
-
-/* Magento console installer and uninstaller stub */
+ */
\ No newline at end of file
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
index 0cd631bf84000bc11af10f98f8c5323a8b9a4ffb..6db1c505bff49c76b7f1472e68c6f83022d73eb4 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_dist/config.php.dist
@@ -11,7 +11,7 @@ return array(
         'installation' => array(
             'options' => array(
                 'backend_frontname' => 'backend',
-                'admin_username' => 'admin',
+                'admin_user' => 'admin',
                 'admin_password' => 'password1',
             ),
         ),
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
index 2b9ae184e4992ef733eea09018062572bf32aab3..463b896d34d68ed13d2a2b1dd7c1c70e1d8e9126 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php
@@ -11,7 +11,7 @@ return [
         'installation' => [
             'options' => [
                 'backend_frontname' => 'backend',
-                'admin_username' => 'admin',
+                'admin_user' => 'admin',
                 'admin_password' => 'password1',
             ],
         ],
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
index 3683444b83ec9d789b85c0fb65de468d69470ea0..577aadcc45bac471f1262da433d3ae0decc30fd3 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/bootstrap/config_normal/config.php.dist
@@ -11,7 +11,7 @@ return array(
         'installation' => array(
             'options' => array(
                 'backend_frontname' => 'backend',
-                'admin_username' => 'admin',
+                'admin_user' => 'admin',
                 'admin_password' => 'password1',
             ),
         ),
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
index 71ccf65e663e82806a1a7ed62047427848b32367..eaa852c5e31a6ece36b932dfac4c552430aee3dd 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/config_data.php
@@ -13,7 +13,7 @@ return [
                 'option1' => 'value 1',
                 'option2' => 'value 2',
                 'backend_frontname' => 'backend',
-                'admin_username' => 'admin',
+                'admin_user' => 'admin',
                 'admin_password' => 'password1',
             ],
         ],
diff --git a/dev/tests/performance/testsuite/backend.jmx b/dev/tests/performance/testsuite/backend.jmx
index 676738bf52fca0704c7d0423b354fb8cc2677d68..fbf480529e8084e7895f66a1541972d697f9e046 100644
--- a/dev/tests/performance/testsuite/backend.jmx
+++ b/dev/tests/performance/testsuite/backend.jmx
@@ -25,9 +25,9 @@
             <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="ADMIN_USERNAME" elementType="Argument">
-            <stringProp name="Argument.name">ADMIN_USERNAME</stringProp>
-            <stringProp name="Argument.value">${__P(admin_username,admin)}</stringProp>
+          <elementProp name="ADMIN_USER" elementType="Argument">
+            <stringProp name="Argument.name">ADMIN_USER</stringProp>
+            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
diff --git a/dev/tests/performance/testsuite/checkout.jmx b/dev/tests/performance/testsuite/checkout.jmx
index d456fecd95ab1f6b634fec4e1e95de92482da39c..5dda04cb25a9e0a66328da0833506d92c7f7a71a 100644
--- a/dev/tests/performance/testsuite/checkout.jmx
+++ b/dev/tests/performance/testsuite/checkout.jmx
@@ -45,9 +45,9 @@
             <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="ADMIN_USERNAME" elementType="Argument">
-            <stringProp name="Argument.name">ADMIN_USERNAME</stringProp>
-            <stringProp name="Argument.value">${__P(admin_username,admin)}</stringProp>
+          <elementProp name="ADMIN_USER" elementType="Argument">
+            <stringProp name="Argument.name">ADMIN_USER</stringProp>
+            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
diff --git a/dev/tests/performance/testsuite/product_edit.jmx b/dev/tests/performance/testsuite/product_edit.jmx
index 67fb78717f44d4004e5a090a50f44c97f26b4403..199c36235c16396d48dcfed93ed116ec14dd5b72 100644
--- a/dev/tests/performance/testsuite/product_edit.jmx
+++ b/dev/tests/performance/testsuite/product_edit.jmx
@@ -35,9 +35,9 @@
             <stringProp name="Argument.value">${__P(loops,1)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
-          <elementProp name="ADMIN_USERNAME" elementType="Argument">
-            <stringProp name="Argument.name">ADMIN_USERNAME</stringProp>
-            <stringProp name="Argument.value">${__P(admin_username,admin)}</stringProp>
+          <elementProp name="ADMIN_USER" elementType="Argument">
+            <stringProp name="Argument.name">ADMIN_USER</stringProp>
+            <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
           </elementProp>
           <elementProp name="ADMIN_PASSWORD" elementType="Argument">
diff --git a/dev/tests/performance/testsuite/reusable/admin_login.jmx b/dev/tests/performance/testsuite/reusable/admin_login.jmx
index 96d8b96335ba6781c68e07645844f0665bc4e80a..6d271217d8989d6d97eb0aaf52f9627c5ddcb9f8 100644
--- a/dev/tests/performance/testsuite/reusable/admin_login.jmx
+++ b/dev/tests/performance/testsuite/reusable/admin_login.jmx
@@ -10,7 +10,7 @@
 <jmeterTestPlan version="1.2" properties="2.4" jmeter="2.9 r1437961">
   <hashTree>
     <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Admin - Login" enabled="true">
-      <stringProp name="TestPlan.comments">Reusable scenario to log-in to admin backend. Needs: HOST, ADMIN_PATH, ADMIN_USERNAME, ADMIN_PASSWORD, Http Cookie Manager</stringProp>
+      <stringProp name="TestPlan.comments">Reusable scenario to log-in to admin backend. Needs: HOST, ADMIN_PATH, ADMIN_USER, ADMIN_PASSWORD, Http Cookie Manager</stringProp>
       <boolProp name="TestPlan.functional_mode">false</boolProp>
       <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
       <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
@@ -77,7 +77,7 @@
             <collectionProp name="Arguments.arguments">
               <elementProp name="login[username]" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value">${ADMIN_USERNAME}</stringProp>
+                <stringProp name="Argument.value">${ADMIN_USER}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
                 <boolProp name="HTTPArgument.use_equals">true</boolProp>
                 <stringProp name="Argument.name">login[username]</stringProp>
@@ -110,7 +110,7 @@
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert logged-in" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="934841248">${ADMIN_USERNAME}</stringProp>
+              <stringProp name="934841248">${ADMIN_USER}</stringProp>
               <stringProp name="-989788387">Account Setting</stringProp>
               <stringProp name="374398571">Sign Out</stringProp>
             </collectionProp>
@@ -162,9 +162,9 @@
               <stringProp name="Argument.value">${__P(path,/)}${__P(backend_frontname,backend)}/</stringProp>
               <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
-            <elementProp name="ADMIN_USERNAME" elementType="Argument">
-              <stringProp name="Argument.name">ADMIN_USERNAME</stringProp>
-              <stringProp name="Argument.value">${__P(admin_username,admin)}</stringProp>
+            <elementProp name="ADMIN_USER" elementType="Argument">
+              <stringProp name="Argument.name">ADMIN_USER</stringProp>
+              <stringProp name="Argument.value">${__P(admin_user,admin)}</stringProp>
               <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
             <elementProp name="ADMIN_PASSWORD" elementType="Argument">
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
index 0d5d3848cfe6a4cc34ec66e67c47b5dbe432755f..b190aee7f88acc5bd18af6e1f986472dd6c35627 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
@@ -69,7 +69,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
 
                 $this->_assertClassesExist($classes, $file);
             },
-            \Magento\Framework\App\Utility\Files::init()->getPhpFiles()
+            \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, true, true, true, false)
         );
     }
 
@@ -530,29 +530,11 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
     {
         $files = \Magento\Framework\App\Utility\Files::init();
         $errors = [];
-        $fileList = $files->getFiles(
-            [
-                BP . '/dev/tests/integration',
-                BP . '/app/code/*/*/Test/Unit',
-                BP . '/lib/internal/*/*/*/Test/Unit',
-                BP . '/lib/internal/Magento/Framework/Test/Unit',
-                BP . '/dev/tools/Magento/Tools/*/Test/Unit',
-                BP . '/setup/src/Magento/Setup/Test/Unit',
-            ],
-            '*.php'
-        );
-        foreach ($fileList as $file) {
+        foreach ($files->getFiles([BP . '/dev/tests/{integration,unit}'], '*') as $file) {
             $code = file_get_contents($file);
-            if (preg_match_all(
-                '/@covers(DefaultClass)?\s+([\w\\\\]+)(::([\w\\\\]+))?/',
-                $code,
-                $matchesAll,
-                PREG_SET_ORDER
-            )) {
-                foreach ($matchesAll as $matches) {
-                    if ($this->isNonexistentEntityCovered($matches)) {
-                        $errors[] = $file . ': ' . $matches[0];
-                    }
+            if (preg_match('/@covers(DefaultClass)?\s+([\w\\\\]+)(::([\w\\\\]+))?/', $code, $matches)) {
+                if ($this->isNonexistentEntityCovered($matches)) {
+                    $errors[] = $file . ': ' . $matches[0];
                 }
             }
         }
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php
index 1d5e17894031ef8128770154c92cf7816bb05a55..834e90911948bcba3d3ecc1a6dd945fbd9ef8988 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php
@@ -322,7 +322,7 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
 
     /**
      * Collect redundant dependencies
-     *
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      * @test
      * @depends testUndeclared
      */
@@ -331,6 +331,7 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
         foreach (array_keys(self::$_mapDependencies) as $module) {
             $declared = $this->_getDependencies($module, self::TYPE_HARD, self::MAP_TYPE_DECLARED);
             $found = $this->_getDependencies($module, self::TYPE_HARD, self::MAP_TYPE_FOUND);
+            $found['Magento\Framework'] = 'Magento\Framework';
             $this->_setDependencies($module, self::TYPE_HARD, self::MAP_TYPE_REDUNDANT, array_diff($declared, $found));
         }
     }
@@ -427,7 +428,7 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
             $files,
             $this->_prepareFiles(
                 'php',
-                \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, true),
+                \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, true, false),
                 true
             )
         );
@@ -489,7 +490,7 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
         $pattern = '/(?<namespace>[A-Z][a-z]+)[_\/\\\\](?<module>[A-Z][a-zA-Z]+)\/Controller\/' .
             '(?<path>[\/\w]*).php/';
 
-        $files = \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, false);
+        $files = \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, false, false);
         foreach ($files as $file) {
             if (preg_match($pattern, $file, $matches)) {
                 $module = $matches['namespace'] . '\\' . $matches['module'];
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlocksTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlocksTest.php
index ea2765ce171036f64a88335bd242ad4ff7bdbea4..16c026a76a57eba3b88e91c1acac28b2bdf85d39 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlocksTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Layout/BlocksTest.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Test\Integrity\Layout;
 
+use Magento\Framework\App\Utility\Files;
+
 class BlocksTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -24,7 +26,7 @@ class BlocksTest extends \PHPUnit_Framework_TestCase
      */
     public static function setUpBeforeClass()
     {
-        foreach (\Magento\Framework\App\Utility\Files::init()->getLayoutFiles([], false) as $file) {
+        foreach (Files::init()->getLayoutFiles([], false) as $file) {
             $xml = simplexml_load_file($file);
             $elements = $xml->xpath('/layout//*[self::container or self::block]') ?: [];
             /** @var $node \SimpleXMLElement */
@@ -94,7 +96,7 @@ class BlocksTest extends \PHPUnit_Framework_TestCase
     public function getChildBlockDataProvider()
     {
         $result = [];
-        foreach (\Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, true, false) as $file) {
+        foreach (Files::init()->getPhpFiles(true, false, true, false, false) as $file) {
             $aliases = \Magento\Framework\App\Utility\Classes::getAllMatches(
                 file_get_contents($file),
                 '/\->getChildBlock\(\'([^\']+)\'\)/x'
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
index 3f6f7bfc288ee5b93346a83c38095c467e60604c..8d6cfb9d34ced8af8e26a9f4dfab7a415ab610fa 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
@@ -85,7 +85,7 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
                     );
                 }
             },
-            $files->getPhpFiles(false, true, false)
+            $files->getPhpFiles(false, true, false, true, false)
         );
     }
 
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ClassesTest.php
index 69688b876fff576a26792afe985d4c246b04e8b5..593dd9d1c16bc91581c77c4362c4f384e970e8f6 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/ClassesTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ClassesTest.php
@@ -22,7 +22,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                 $classes = \Magento\Framework\App\Utility\Classes::collectPhpCodeClasses(file_get_contents($file));
                 $this->_assertNonFactoryName($classes, $file);
             },
-            \Magento\Framework\App\Utility\Files::init()->getPhpFiles()
+            \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, true, true, true, false)
         );
     }
 
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/TableTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/TableTest.php
index c1c8f263120d80a785bae0f27d3d3b4fbfe1e60d..6e99ef361a84dc2a1d2818e7f1a015f77d951639 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/TableTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/TableTest.php
@@ -32,7 +32,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
                 $message = $this->_composeFoundsMessage($legacyTables);
                 $this->assertEmpty($message, $message);
             },
-            \Magento\Framework\App\Utility\Files::init()->getPhpFiles()
+            \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, true, true, true, false)
         );
     }
 
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 5087bd50216f4b22bcea2db7700716403ca29245..ea38ddcc122e4c6ee620adfe14fc76ebb806a43c 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -3118,14 +3118,6 @@ return [
     ['Magento\LocaleFactory'],
     ['Magento\Framework\LocaleFactory'],
     ['Magento\Core\Helper\Data', 'Magento\Framework\Json\Helper\Data'],
-    ['Magento\Framework\App\DeploymentConfig\BackendConfig'],
-    ['Magento\Framework\App\DeploymentConfig\DbConfig'],
-    ['Magento\Framework\App\DeploymentConfig\InstallConfig'],
-    ['Magento\Framework\App\DeploymentConfig\ResourceConfig'],
-    ['Magento\Framework\App\DeploymentConfig\SessionConfig'],
-    ['Magento\Framework\App\DeploymentConfig\CacheConfig'],
-    ['Magento\Setup\Model\DeploymentConfigMapper'],
-    ['Magento\Framework\App\DeploymentConfig\EncryptConfig'],
     ['Magento\Backup\Exception'],
     ['Magento\Catalog\Exception'],
     ['Magento\Reports\Exception'],
@@ -3146,4 +3138,18 @@ return [
     ['Magento\CatalogRule\CatalogRuleException'],
     ['Magento\Payment\Exception'],
     ['Magento\UrlRewrite\Model\Storage\DuplicateEntryException'],
+    ['Magento\Framework\App\DeploymentConfig\BackendConfig'],
+    ['Magento\Framework\App\DeploymentConfig\DbConfig'],
+    ['Magento\Framework\App\DeploymentConfig\InstallConfig'],
+    ['Magento\Framework\App\DeploymentConfig\ResourceConfig'],
+    ['Magento\Framework\App\DeploymentConfig\SessionConfig'],
+    ['Magento\Framework\App\DeploymentConfig\CacheConfig'],
+    ['Magento\Setup\Model\DeploymentConfigMapper'],
+    ['Magento\Framework\App\DeploymentConfig\EncryptConfig'],
+    ['Magento\Setup\Mvc\Console\RouteListener'],
+    ['Magento\Setup\Mvc\Console\RouteMatcher'],
+    ['Magento\Setup\Mvc\Console\VerboseValidator'],
+    ['Magento\Setup\Controller\ConsoleController'],
+    ['Magento\Setup\Model\UserConfigurationDataMapper', 'Magento\Setup\Model\StoreConfigurationDataMapper'],
+    ['Magento\Framework\App\State\Cleanup', 'Magento\Framework\App\State\CleanupFiles'],
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 7baeb9bac60b7ecbb782de7407a87d7033367831..6a1f2846a85df46a6293a7fc8c210feddce5d60d 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2155,4 +2155,13 @@ return [
     ['_isCacheEnabled', 'Magento\Eav\Model\Config'],
     ['_createCustomerAttribute', '\Magento\Customer\Model\Customer'],
     ['prepareCatalogProductPriceIndexTable', 'Magento\CatalogRule\Model\Observer'],
+    ['joinOrders', 'Magento\Reports\Model\Resource\Customer\Collection'],
+    ['addOrdersCount', 'Magento\Reports\Model\Resource\Customer\Collection'],
+    ['addSumAvgTotals', 'Magento\Reports\Model\Resource\Customer\Collection'],
+    ['orderByTotalAmount', 'Magento\Reports\Model\Resource\Customer\Collection'],
+    ['addOrdersCount', 'Magento\Reports\Model\Resource\Product\Collection'],
+    ['addOrderedQty', 'Magento\Reports\Model\Resource\Product\Collection'],
+    ['prepareForProductsInCarts', 'Magento\Reports\Model\Resource\Quote\Collection'],
+    ['getOrdersSubSelect', 'Magento\Reports\Model\Resource\Quote\Collection'],
+    ['isOrderIncrementIdUsed', 'Magento\Quote\Model\Resource\Quote'],
 ];
diff --git a/dev/tools/Magento/Tools/Migration/factory_names.php b/dev/tools/Magento/Tools/Migration/factory_names.php
index 9e17d616dbe8eeea9c9c7f7c2246ab46507f6b77..96b3dbe8c1b2ed15ca957706b2e1fb6159cc4306 100644
--- a/dev/tools/Magento/Tools/Migration/factory_names.php
+++ b/dev/tools/Magento/Tools/Migration/factory_names.php
@@ -8,7 +8,7 @@
 require realpath(dirname(dirname(dirname(dirname(dirname(__DIR__)))))) . '/dev/tests/static/framework/bootstrap.php';
 
 // PHP code
-foreach (\Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, true, true, false) as $file) {
+foreach (\Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, true, true, false, false) as $file) {
     $content = file_get_contents($file);
     $classes = \Magento\Framework\App\Utility\Classes::collectPhpCodeClasses($content);
     $factoryNames = array_filter($classes, 'isFactoryName');
diff --git a/dev/tools/Magento/Tools/Migration/factory_table_names.php b/dev/tools/Magento/Tools/Migration/factory_table_names.php
index f38c8a35c724b07349d98a5b7e63b5b6cded5eac..6dfaa0a8e22fde0b3778387594b800a9d47e316d 100644
--- a/dev/tools/Magento/Tools/Migration/factory_table_names.php
+++ b/dev/tools/Magento/Tools/Migration/factory_table_names.php
@@ -32,7 +32,7 @@ require realpath(dirname(dirname(dirname(__DIR__)))) . '/dev/tests/static/framew
 $tablesAssociation = getFilesCombinedArray(__DIR__ . '/FactoryTableNames', 'replace_*.php');
 $blackList = getFilesCombinedArray(__DIR__ . '/FactoryTableNames', 'blacklist_*.php');
 
-$phpFiles = \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, false);
+$phpFiles = \Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, false, false);
 
 $replacementResult = false;
 if (!$isSearchTables || $isDryRunMode) {
diff --git a/dev/tools/Magento/Tools/Migration/get_aliases_map.php b/dev/tools/Magento/Tools/Migration/get_aliases_map.php
index 0db788c57f8900322e3de7c1d75c770c319717d6..d1abe748f9204b671afa01cb8fd07e8100f9b3bb 100644
--- a/dev/tools/Magento/Tools/Migration/get_aliases_map.php
+++ b/dev/tools/Magento/Tools/Migration/get_aliases_map.php
@@ -39,7 +39,7 @@ $utilityFiles = new Magento\Framework\App\Utility\Files($magentoBaseDir);
 $map = [];
 $compositeModules = getFilesCombinedArray(__DIR__ . '/aliases_map', '/^composite_modules_.*\.php$/');
 // PHP code
-foreach ($utilityFiles->getPhpFiles(true, true, true, false) as $file) {
+foreach ($utilityFiles->getPhpFiles(true, true, true, false, false) as $file) {
     $content = file_get_contents($file);
     $classes = \Magento\Framework\App\Utility\Classes::collectPhpCodeClasses($content);
     if ($classes) {
diff --git a/dev/tools/performance-toolkit/fixtures/configurable_products.php b/dev/tools/performance-toolkit/fixtures/configurable_products.php
index af3a5b5c6cd2bbc1da4eb0aa299971b436b43f69..a3aa8f8ba8d244eba56a8ca2e184be05f7cdbbce 100644
--- a/dev/tools/performance-toolkit/fixtures/configurable_products.php
+++ b/dev/tools/performance-toolkit/fixtures/configurable_products.php
@@ -885,7 +885,7 @@ class ConfigurableProductsFixture extends \Magento\ToolkitFramework\Fixture
         /** @var \Magento\ImportExport\Model\Import $import */
         $import = $this->application->getObjectManager()->create(
             'Magento\ImportExport\Model\Import',
-            ['data' => ['entity' => 'catalog_product', 'behavior' => 'append']]
+            ['data' => ['entity' => 'catalog_product', 'behavior' => 'replace']]
         );
 
         $source = new \Magento\ToolkitFramework\ImportExport\Fixture\Complex\Generator($pattern, $configurablesCount);
diff --git a/lib/internal/Magento/Framework/App/Bootstrap.php b/lib/internal/Magento/Framework/App/Bootstrap.php
index 2099ee76e92d7d14fdbf45bca1f4b20a61d48b45..aaf238eadacaa007b8a7abe560095b6125d99c40 100644
--- a/lib/internal/Magento/Framework/App/Bootstrap.php
+++ b/lib/internal/Magento/Framework/App/Bootstrap.php
@@ -274,11 +274,11 @@ class Bootstrap
         $isOn = $this->maintenance->isOn(isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : '');
         if ($isOn && !$isExpected) {
             $this->errorCode = self::ERR_MAINTENANCE;
-            throw new \Exception('Unable to proceed: the maintenance mode is enabled.');
+            throw new \Exception('Unable to proceed: the maintenance mode is enabled. ');
         }
         if (!$isOn && $isExpected) {
             $this->errorCode = self::ERR_MAINTENANCE;
-            throw new \Exception('Unable to proceed: the maintenance mode must be enabled first.');
+            throw new \Exception('Unable to proceed: the maintenance mode must be enabled first. ');
         }
     }
 
@@ -298,11 +298,11 @@ class Bootstrap
         $isInstalled = $this->isInstalled();
         if (!$isInstalled && $isExpected) {
             $this->errorCode = self::ERR_IS_INSTALLED;
-            throw new \Exception('Application is not installed yet.');
+            throw new \Exception('Error: Application is not installed yet. ');
         }
         if ($isInstalled && !$isExpected) {
             $this->errorCode = self::ERR_IS_INSTALLED;
-            throw new \Exception('Application is already installed.');
+            throw new \Exception('Error: Application is already installed. ');
         }
     }
 
@@ -406,7 +406,7 @@ class Bootstrap
         if ($this->isDeveloperMode()) {
             echo $e;
         } else {
-            $message = "An error has happened during application run. See debug log for details.\n";
+            $message = "An error has happened during application run. See exception log for details.\n";
             try {
                 if (!$this->objectManager) {
                     throw new \DomainException();
diff --git a/lib/internal/Magento/Framework/App/State/Cleanup.php b/lib/internal/Magento/Framework/App/State/CleanupFiles.php
similarity index 50%
rename from lib/internal/Magento/Framework/App/State/Cleanup.php
rename to lib/internal/Magento/Framework/App/State/CleanupFiles.php
index 2a832f611b739386b9a244621dfe14b489dd335c..5509d78d60dc0dc0c7832db3da324afdd31ea501 100644
--- a/lib/internal/Magento/Framework/App/State/Cleanup.php
+++ b/lib/internal/Magento/Framework/App/State/CleanupFiles.php
@@ -6,23 +6,15 @@
 
 namespace Magento\Framework\App\State;
 
-use Magento\Framework\App\Cache\Frontend\Pool;
 use Magento\Framework\Filesystem;
+use Magento\Framework\Exception\FileSystemException;
 use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\View\Asset\Source;
 
 /**
  * A service for cleaning up application state
  */
-class Cleanup
+class CleanupFiles
 {
-    /**
-     * Cache frontend pool
-     *
-     * @var Pool
-     */
-    private $cachePool;
-
     /**
      * File system
      *
@@ -33,58 +25,60 @@ class Cleanup
     /**
      * Constructor
      *
-     * @param Pool $cachePool
      * @param Filesystem $filesystem
      */
-    public function __construct(Pool $cachePool, Filesystem $filesystem)
+    public function __construct(Filesystem $filesystem)
     {
-        $this->cachePool = $cachePool;
         $this->filesystem = $filesystem;
     }
 
-    /**
-     * Clears all caches
-     *
-     * @return void
-     */
-    public function clearCaches()
-    {
-        /** @var \Magento\Framework\Cache\FrontendInterface $frontend */
-        foreach ($this->cachePool as $frontend) {
-            $frontend->clean();
-        }
-    }
-
     /**
      * Clears all files that are subject of code generation
      *
-     * @return void
+     * @return string[]
      */
     public function clearCodeGeneratedFiles()
     {
-        $this->clearCodeGeneratedClasses();
-        $this->clearMaterializedViewFiles();
+        return array_merge(
+            $this->clearCodeGeneratedClasses(),
+            $this->clearMaterializedViewFiles()
+        );
     }
 
     /**
      * Clears code-generated classes
      *
-     * @return void
+     * @return string[]
      */
     public function clearCodeGeneratedClasses()
     {
-        $this->emptyDir(DirectoryList::GENERATION);
+        return $this->emptyDir(DirectoryList::GENERATION);
     }
 
     /**
      * Clears materialized static view files
      *
-     * @return void
+     * @return string[]
      */
     public function clearMaterializedViewFiles()
     {
-        $this->emptyDir(DirectoryList::STATIC_VIEW);
-        $this->emptyDir(DirectoryList::VAR_DIR, DirectoryList::TMP_MATERIALIZATION_DIR);
+        return array_merge(
+            $this->emptyDir(DirectoryList::STATIC_VIEW),
+            $this->emptyDir(DirectoryList::VAR_DIR, DirectoryList::TMP_MATERIALIZATION_DIR)
+        );
+    }
+
+    /**
+     * Clears all files
+     *
+     * @return string[]
+     */
+    public function clearAllFiles()
+    {
+        return array_merge(
+            $this->emptyDir(DirectoryList::STATIC_VIEW),
+            $this->emptyDir(DirectoryList::VAR_DIR)
+        );
     }
 
     /**
@@ -92,15 +86,29 @@ class Cleanup
      *
      * @param string $code
      * @param string|null $subPath
-     * @return void
+     * @return string[]
      */
     private function emptyDir($code, $subPath = null)
     {
+        $messages = [];
+
         $dir = $this->filesystem->getDirectoryWrite($code);
+        $dirPath = $dir->getAbsolutePath();
+        if (!$dir->isExist()) {
+            $messages[] = "The directory '{$dirPath}' doesn't exist - skipping cleanup";
+            return $messages;
+        }
         foreach ($dir->search('*', $subPath) as $path) {
             if (false === strpos($path, '.')) {
-                $dir->delete($path);
+                $messages[] = $dirPath . $path;
+                try {
+                    $dir->delete($path);
+                } catch (FilesystemException $e) {
+                    $messages[] = $e->getMessage();
+                }
             }
         }
+
+        return $messages;
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/State/CleanupTest.php b/lib/internal/Magento/Framework/App/Test/Unit/State/CleanupFilesTest.php
similarity index 57%
rename from lib/internal/Magento/Framework/App/Test/Unit/State/CleanupTest.php
rename to lib/internal/Magento/Framework/App/Test/Unit/State/CleanupFilesTest.php
index ad3740f90d515796723b9503609e734adf506a09..f1290dcc139bc8bef9d1efff92947d1e2f5d6a11 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/State/CleanupTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/State/CleanupFilesTest.php
@@ -6,63 +6,27 @@
 
 namespace Magento\Framework\App\Test\Unit\State;
 
-use \Magento\Framework\App\State\Cleanup;
+use \Magento\Framework\App\State\CleanupFiles;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filesystem\DriverPool;
 
-class CleanupTest extends \PHPUnit_Framework_TestCase
+class CleanupFilesTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cachePool;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject[]
-     */
-    private $cache;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
     private $filesystem;
 
     /**
-     * @var Cleanup
+     * @var CleanupFiles
      */
     private $object;
 
     protected function setUp()
     {
-        $this->cachePool = $this->getMock('Magento\Framework\App\Cache\Frontend\Pool', [], [], '', false);
-        $this->cache = [
-            $this->getMockForAbstractClass('Magento\Framework\Cache\FrontendInterface'),
-            $this->getMockForAbstractClass('Magento\Framework\Cache\FrontendInterface'),
-        ];
         $this->filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
-        $this->object = new Cleanup($this->cachePool, $this->filesystem);
-    }
-
-    public function testClearCaches()
-    {
-        $this->mockCachePoolIterator();
-        $this->cache[0]->expects($this->once())->method('clean');
-        $this->cache[1]->expects($this->once())->method('clean');
-        $this->object->clearCaches();
-    }
-
-    /**
-     * Mocks cache pool iteration through 2 items
-     *
-     * @return void
-     */
-    private function mockCachePoolIterator()
-    {
-        $this->cachePool->expects($this->any())->method('valid')->will($this->onConsecutiveCalls(true, true, false));
-        $this->cachePool->expects($this->any())
-            ->method('current')
-            ->will($this->onConsecutiveCalls($this->cache[0], $this->cache[1]));
+        $this->object = new CleanupFiles($this->filesystem);
     }
 
     public function testClearCodeGeneratedClasses()
@@ -97,6 +61,7 @@ class CleanupTest extends \PHPUnit_Framework_TestCase
         $dir = $this->getMockForAbstractClass('Magento\Framework\Filesystem\Directory\WriteInterface');
         $dir->expects($this->once())->method('search')->with('*', $subPath)->willReturn(['one', 'two']);
         $dir->expects($this->exactly(2))->method('delete');
+        $dir->expects($this->once())->method('isExist')->will($this->returnValue(true));
         return $dir;
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Utility/Classes.php b/lib/internal/Magento/Framework/App/Utility/Classes.php
index 6671bd6a0464da30ef79dd001742cd2ff6ad43ef..f49118641b3f4de5d3dd08e4cef4ddd9d46bef51 100644
--- a/lib/internal/Magento/Framework/App/Utility/Classes.php
+++ b/lib/internal/Magento/Framework/App/Utility/Classes.php
@@ -7,6 +7,8 @@
  */
 namespace Magento\Framework\App\Utility;
 
+use Magento\Framework\App\Utility\Files;
+
 class Classes
 {
     /**
@@ -185,11 +187,11 @@ class Classes
     public static function collectModuleClasses($subTypePattern = '[A-Za-z]+')
     {
         $pattern = '/^' . preg_quote(
-            \Magento\Framework\App\Utility\Files::init()->getPathToSource(),
+            Files::init()->getPathToSource(),
             '/'
         ) . '\/app\/code\/([A-Za-z]+)\/([A-Za-z]+)\/(' . $subTypePattern . '\/.+)\.php$/';
         $result = [];
-        foreach (\Magento\Framework\App\Utility\Files::init()->getPhpFiles(true, false, false, false) as $file) {
+        foreach (Files::init()->getPhpFiles(true, false, false, false, false) as $file) {
             if (preg_match($pattern, $file, $matches)) {
                 $module = "{$matches[1]}_{$matches[2]}";
                 $class = "{$module}" . '\\' . str_replace(
@@ -214,7 +216,7 @@ class Classes
         if (!empty(self::$_virtualClasses)) {
             return self::$_virtualClasses;
         }
-        $configFiles = \Magento\Framework\App\Utility\Files::init()->getDiConfigs();
+        $configFiles = Files::init()->getDiConfigs();
         foreach ($configFiles as $fileName) {
             $configDom = new \DOMDocument();
             $configDom->load($fileName);
diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php
index 15869c4be7c49c67c886bab1b14484c2f5b1b5ea..57fe340acda362fa1a17839ee8c54c515f5907cb 100644
--- a/lib/internal/Magento/Framework/App/Utility/Files.php
+++ b/lib/internal/Magento/Framework/App/Utility/Files.php
@@ -109,9 +109,10 @@ class Files
      * @param bool $otherCode non-application PHP-code (doesn't include "dev" directory)
      * @param bool $templates application PHTML-code
      * @param bool $asDataSet
+     * @param bool $tests tests folder
      * @return array
      */
-    public function getPhpFiles($appCode = true, $otherCode = true, $templates = true, $asDataSet = true)
+    public function getPhpFiles($appCode = true, $otherCode = true, $templates = true, $asDataSet = true, $tests = true)
     {
         $key = __METHOD__ . "/{$this->_path}/{$appCode}/{$otherCode}/{$templates}";
         if (!isset(self::$_cache[$key])) {
@@ -137,6 +138,12 @@ class Files
                     self::getFiles(["{$this->_path}/dev/tools/Magento/Tools/SampleData"], '*.php')
                 );
             }
+            if ($tests) {
+                $files = array_merge(
+                    $files,
+                    self::getFiles(["{$this->_path}/dev/tests"], '*.php')
+                );
+            }
             if ($templates) {
                 $files = array_merge($files, $this->getPhtmlFiles(false, false));
             }
diff --git a/lib/internal/Magento/Framework/Config/ConfigGenerator.php b/lib/internal/Magento/Framework/Config/ConfigGenerator.php
index 8930487dd35c7950364fbf994eab3a0715045517..c7f4ac934ae47cf91fd90dff233df5c24a611a3c 100644
--- a/lib/internal/Magento/Framework/Config/ConfigGenerator.php
+++ b/lib/internal/Magento/Framework/Config/ConfigGenerator.php
@@ -25,7 +25,7 @@ class ConfigGenerator
         ConfigOptionsList::INPUT_KEY_DB_HOST => ConfigOptionsList::KEY_HOST,
         ConfigOptionsList::INPUT_KEY_DB_NAME => ConfigOptionsList::KEY_NAME,
         ConfigOptionsList::INPUT_KEY_DB_USER => ConfigOptionsList::KEY_USER,
-        ConfigOptionsList::INPUT_KEY_DB_PASS => ConfigOptionsList::KEY_PASS,
+        ConfigOptionsList::INPUT_KEY_DB_PASSWORD => ConfigOptionsList::KEY_PASSWORD,
         ConfigOptionsList::INPUT_KEY_DB_PREFIX => ConfigOptionsList::KEY_PREFIX,
         ConfigOptionsList::INPUT_KEY_DB_MODEL => ConfigOptionsList::KEY_MODEL,
         ConfigOptionsList::INPUT_KEY_DB_INIT_STATEMENTS => ConfigOptionsList::KEY_INIT_STATEMENTS,
@@ -152,7 +152,7 @@ class ConfigGenerator
             ConfigOptionsList::INPUT_KEY_DB_HOST,
             ConfigOptionsList::INPUT_KEY_DB_NAME,
             ConfigOptionsList::INPUT_KEY_DB_USER,
-            ConfigOptionsList::INPUT_KEY_DB_PASS,
+            ConfigOptionsList::INPUT_KEY_DB_PASSWORD,
             ConfigOptionsList::INPUT_KEY_DB_MODEL,
             ConfigOptionsList::INPUT_KEY_DB_INIT_STATEMENTS,
         ];
diff --git a/lib/internal/Magento/Framework/Config/ConfigOptionsList.php b/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
index 817835ed0d0fdb6460653e50c330fb2ec2743654..ac1a90652f40c07dc382b094e655a4cd289a5700 100644
--- a/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
+++ b/lib/internal/Magento/Framework/Config/ConfigOptionsList.php
@@ -37,7 +37,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
     const INPUT_KEY_DB_HOST = 'db_host';
     const INPUT_KEY_DB_NAME = 'db_name';
     const INPUT_KEY_DB_USER = 'db_user';
-    const INPUT_KEY_DB_PASS = 'db_pass';
+    const INPUT_KEY_DB_PASSWORD = 'db_password';
     const INPUT_KEY_DB_PREFIX = 'db_prefix';
     const INPUT_KEY_DB_MODEL = 'db_model';
     const INPUT_KEY_DB_INIT_STATEMENTS = 'db_init_statements';
@@ -62,7 +62,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
     const KEY_HOST = 'host';
     const KEY_NAME = 'dbname';
     const KEY_USER = 'username';
-    const KEY_PASS = 'password';
+    const KEY_PASSWORD = 'password';
     const KEY_PREFIX = 'table_prefix';
     const KEY_MODEL = 'model';
     const KEY_INIT_STATEMENTS = 'initStatements';
@@ -155,9 +155,9 @@ class ConfigOptionsList implements ConfigOptionsListInterface
                 'root'
             ),
             new TextConfigOption(
-                self::INPUT_KEY_DB_PASS,
+                self::INPUT_KEY_DB_PASSWORD,
                 TextConfigOption::FRONTEND_WIZARD_PASSWORD,
-                self::CONFIG_PATH_DB_CONNECTION_DEFAULT . self::KEY_PASS,
+                self::CONFIG_PATH_DB_CONNECTION_DEFAULT . self::KEY_PASSWORD,
                 'Database server password',
                 ''
             ),
diff --git a/lib/internal/Magento/Framework/Console/CommandList.php b/lib/internal/Magento/Framework/Console/CommandList.php
index a75d096466bf0bc0a3aefc657cee7eae077cfe60..99519a396d16b66eeaa68481d31514fc85da65e1 100644
--- a/lib/internal/Magento/Framework/Console/CommandList.php
+++ b/lib/internal/Magento/Framework/Console/CommandList.php
@@ -6,12 +6,8 @@
 
 namespace Magento\Framework\Console;
 
-use Magento\Framework\ObjectManagerInterface;
-
 /**
  * Class CommandList has a list of commands, which can be extended via DI configuration.
- *
- * @package Magento\Framework\Console
  */
 class CommandList
 {
diff --git a/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php b/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
index 84ab04e316702c3f3575d9b6bff71bf5db92aff6..ac5f33263ec03c3ac9452229a31c8d0d71690272 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/AdapterInterface.php
@@ -375,7 +375,6 @@ interface AdapterInterface
         $refTableName,
         $refColumnName,
         $onDelete = self::FK_ACTION_CASCADE,
-        $onUpdate = self::FK_ACTION_CASCADE,
         $purge = false,
         $schemaName = null,
         $refSchemaName = null
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index c46f71cf9ebe447a028d6ce512819631ebd463e9..f3bf8e12d893c11bd321989e4786d1d65893976d 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -1071,7 +1071,6 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * REF_TABLE_NAME   => string; reference table name
      * REF_COLUMN_NAME  => string; reference column name
      * ON_DELETE        => string; action type on delete row
-     * ON_UPDATE        => string; action type on update row
      *
      * @param string $tableName
      * @param string $schemaName
@@ -1101,8 +1100,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
                     'REF_SHEMA_NAME'    => isset($match[4]) ? $match[4] : $schemaName,
                     'REF_TABLE_NAME'    => $match[5],
                     'REF_COLUMN_NAME'   => $match[6],
-                    'ON_DELETE'         => isset($match[7]) ? $match[8] : '',
-                    'ON_UPDATE'         => isset($match[9]) ? $match[10] : '',
+                    'ON_DELETE'         => isset($match[7]) ? $match[8] : ''
                 ];
             }
 
@@ -1173,10 +1171,8 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
                     unset($columnDefinition['identity'], $columnDefinition['primary'], $columnDefinition['comment']);
 
                     $onDelete = $options['ON_DELETE'];
-                    $onUpdate = $options['ON_UPDATE'];
 
-                    if ($onDelete == AdapterInterface::FK_ACTION_SET_NULL
-                        || $onUpdate == AdapterInterface::FK_ACTION_SET_NULL) {
+                    if ($onDelete == AdapterInterface::FK_ACTION_SET_NULL) {
                         $columnDefinition['nullable'] = true;
                     }
                     $this->modifyColumn($options['TABLE_NAME'], $options['COLUMN_NAME'], $columnDefinition);
@@ -1186,8 +1182,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
                         $options['COLUMN_NAME'],
                         $options['REF_TABLE_NAME'],
                         $options['REF_COLUMN_NAME'],
-                        ($onDelete) ? $onDelete : AdapterInterface::FK_ACTION_NO_ACTION,
-                        ($onUpdate) ? $onUpdate : AdapterInterface::FK_ACTION_NO_ACTION
+                        ($onDelete) ? $onDelete : AdapterInterface::FK_ACTION_NO_ACTION
                     );
                 }
             }
@@ -1633,15 +1628,13 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
                 $keyData['REF_COLUMN_NAME']
             );
             $onDelete = $this->_getDdlAction($keyData['ON_DELETE']);
-            $onUpdate = $this->_getDdlAction($keyData['ON_UPDATE']);
 
             $table->addForeignKey(
                 $fkName,
                 $keyData['COLUMN_NAME'],
                 $keyData['REF_TABLE_NAME'],
                 $keyData['REF_COLUMN_NAME'],
-                $onDelete,
-                $onUpdate
+                $onDelete
             );
         }
 
@@ -2139,16 +2132,13 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
         if (!empty($relations)) {
             foreach ($relations as $fkData) {
                 $onDelete = $this->_getDdlAction($fkData['ON_DELETE']);
-                $onUpdate = $this->_getDdlAction($fkData['ON_UPDATE']);
-
                 $definition[] = sprintf(
-                    '  CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) ON DELETE %s ON UPDATE %s',
+                    '  CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) ON DELETE %s',
                     $this->quoteIdentifier($fkData['FK_NAME']),
                     $this->quoteIdentifier($fkData['COLUMN_NAME']),
                     $this->quoteIdentifier($fkData['REF_TABLE_NAME']),
                     $this->quoteIdentifier($fkData['REF_COLUMN_NAME']),
-                    $onDelete,
-                    $onUpdate
+                    $onDelete
                 );
             }
         }
@@ -2579,7 +2569,6 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
      * @param string $refTableName
      * @param string $refColumnName
      * @param string $onDelete
-     * @param string $onUpdate
      * @param bool $purge            trying remove invalid data
      * @param string $schemaName
      * @param string $refSchemaName
@@ -2593,7 +2582,6 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
         $refTableName,
         $refColumnName,
         $onDelete = AdapterInterface::FK_ACTION_CASCADE,
-        $onUpdate = AdapterInterface::FK_ACTION_CASCADE,
         $purge = false,
         $schemaName = null,
         $refSchemaName = null
@@ -2616,9 +2604,6 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
         if ($onDelete !== null) {
             $query .= ' ON DELETE ' . strtoupper($onDelete);
         }
-        if ($onUpdate  !== null) {
-            $query .= ' ON UPDATE ' . strtoupper($onUpdate);
-        }
 
         $result = $this->rawQuery($query);
         $this->resetDdlCache($tableName);
diff --git a/lib/internal/Magento/Framework/DB/Ddl/Table.php b/lib/internal/Magento/Framework/DB/Ddl/Table.php
index e42dfa1f6c2d7914b07c10931b5eed2a00805312..eee5ed9bc320a574eec14163bcf05fa4b21fd353 100644
--- a/lib/internal/Magento/Framework/DB/Ddl/Table.php
+++ b/lib/internal/Magento/Framework/DB/Ddl/Table.php
@@ -405,12 +405,11 @@ class Table
      * @param string $refTable      the reference table name
      * @param string $refColumn     the reference table column name
      * @param string $onDelete      the action on delete row
-     * @param string $onUpdate      the action on update
      * @return $this
      * @throws \Zend_Db_Exception
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
-    public function addForeignKey($fkName, $column, $refTable, $refColumn, $onDelete = null, $onUpdate = null)
+    public function addForeignKey($fkName, $column, $refTable, $refColumn, $onDelete = null)
     {
         $upperName = strtoupper($fkName);
 
@@ -429,23 +428,12 @@ class Table
                 $onDelete = self::ACTION_NO_ACTION;
         }
 
-        switch ($onUpdate) {
-            case self::ACTION_CASCADE:
-            case self::ACTION_RESTRICT:
-            case self::ACTION_SET_DEFAULT:
-            case self::ACTION_SET_NULL:
-                break;
-            default:
-                $onUpdate = self::ACTION_NO_ACTION;
-        }
-
         $this->_foreignKeys[$upperName] = [
             'FK_NAME' => $fkName,
             'COLUMN_NAME' => $column,
             'REF_TABLE_NAME' => $refTable,
             'REF_COLUMN_NAME' => $refColumn,
-            'ON_DELETE' => $onDelete,
-            'ON_UPDATE' => $onUpdate,
+            'ON_DELETE' => $onDelete
         ];
 
         return $this;
diff --git a/lib/internal/Magento/Framework/Less/Test/Unit/File/Collector/LibraryTest.php b/lib/internal/Magento/Framework/Less/Test/Unit/File/Collector/LibraryTest.php
index 9dc45f4008b201640712a5a12c5177f2bb61a8b1..1bb6e276c9761f3e69dfc02f3870c9466d845328 100644
--- a/lib/internal/Magento/Framework/Less/Test/Unit/File/Collector/LibraryTest.php
+++ b/lib/internal/Magento/Framework/Less/Test/Unit/File/Collector/LibraryTest.php
@@ -120,7 +120,7 @@ class LibraryTest extends \PHPUnit_Framework_TestCase
         $this->libraryDirectoryMock->expects($this->any())->method('search')->will($this->returnValue($libraryFiles));
         $this->libraryDirectoryMock->expects($this->any())->method('getAbsolutePath')->will($this->returnCallback(
             function ($file) {
-                return '/opt/Magneto/lib/' . $file;
+                return '/opt/Magento/lib/' . $file;
             }
         ));
         $themePath = '/var/Magento/ATheme';
diff --git a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php
index e8ff84ee476765a4ef471c9bc92b3a8489a53e1c..16526b3fb40bfe1526aa06fd9d47080ff5fa318f 100644
--- a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php
+++ b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php
@@ -57,7 +57,8 @@ class DbStatusValidator
                 $formattedErrors = $this->formatErrors($errors);
                 throw new \Magento\Framework\Exception\LocalizedException(
                     new \Magento\Framework\Phrase(
-                        'Please update your database: Run "php -f index.php update" from the Magento root/setup directory. %1The following modules are outdated:%2%3',
+                        'Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory.'
+                        . ' %1The following modules are outdated:%2%3',
                         [PHP_EOL, PHP_EOL, implode(PHP_EOL, $formattedErrors)]
                     )
                 );
diff --git a/lib/internal/Magento/Framework/Module/Status.php b/lib/internal/Magento/Framework/Module/Status.php
index 0c93b19feec2989b781306be7cce4e43b997d3ee..897c7cc10eb1366ef242d9c3037f0ff2cc9ccd96 100644
--- a/lib/internal/Magento/Framework/Module/Status.php
+++ b/lib/internal/Magento/Framework/Module/Status.php
@@ -7,7 +7,6 @@
 namespace Magento\Framework\Module;
 
 use Magento\Framework\App\DeploymentConfig\Writer;
-use Magento\Framework\App\State\Cleanup;
 use Magento\Framework\Config\File\ConfigFilePool;
 
 /**
@@ -38,13 +37,6 @@ class Status
      */
     private $writer;
 
-    /**
-     * Application state cleanup service
-     *
-     * @var Cleanup
-     */
-    private $cleanup;
-
     /**
      * Dependency Checker
      *
@@ -65,7 +57,6 @@ class Status
      * @param ModuleList\Loader $loader
      * @param ModuleList $list
      * @param Writer $writer
-     * @param Cleanup $cleanup
      * @param ConflictChecker $conflictChecker
      * @param DependencyChecker $dependencyChecker
      */
@@ -73,14 +64,12 @@ class Status
         ModuleList\Loader $loader,
         ModuleList $list,
         Writer $writer,
-        Cleanup $cleanup,
         ConflictChecker $conflictChecker,
         DependencyChecker $dependencyChecker
     ) {
         $this->loader = $loader;
         $this->list = $list;
         $this->writer = $writer;
-        $this->cleanup = $cleanup;
         $this->conflictChecker = $conflictChecker;
         $this->dependencyChecker = $dependencyChecker;
     }
@@ -134,7 +123,7 @@ class Status
 
         foreach ($errorModulesConflict as $moduleName => $conflictingModules) {
             if (!empty($conflictingModules)) {
-                $errorMessages[] = "Cannot enable $moduleName, conflicting with other modules:";
+                $errorMessages[] = "Cannot enable $moduleName because it conflicts with other modules:";
                 $errorMessages[] = implode("\n", $conflictingModules);
             }
         }
@@ -163,8 +152,6 @@ class Status
             }
         }
         $this->writer->saveConfig([ConfigFilePool::APP_CONFIG => ['modules' => $result]], true);
-        $this->cleanup->clearCaches();
-        $this->cleanup->clearCodeGeneratedFiles();
     }
 
     /**
@@ -239,9 +226,9 @@ class Status
     private function createVerboseErrorMessage($isEnabled, $moduleName, $missingDependencies)
     {
         if ($isEnabled) {
-            $errorMessages[] = "Cannot enable $moduleName, depending on disabled modules:";
+            $errorMessages[] = "Cannot enable $moduleName because it depends on disabled modules:";
         } else {
-            $errorMessages[] = "Cannot disable $moduleName, modules depending on it:";
+            $errorMessages[] = "Cannot disable $moduleName because modules depend on it:";
         }
         foreach ($missingDependencies as $errorModule => $path) {
                 $errorMessages[] = "$errorModule: " . implode('->', $path);
diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php
index 10e21e701802b59a7be38144bb7fb5d1cbf684d6..b3b521a216ec13af3a473786bf6cb3787da43463 100644
--- a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php
+++ b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php
@@ -117,7 +117,7 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase
      *
      * @dataProvider aroundDispatchExceptionDataProvider
      * @expectedException \Magento\Framework\Exception\LocalizedException
-     * @expectedExceptionMessage Please update your database:
+     * @expectedExceptionMessage Please upgrade your database:
      */
     public function testAroundDispatchException(array $dbVersionErrors)
     {
diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/StatusTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/StatusTest.php
index 697677f6b1044bb727462becdfe747a70278ebd9..dbdf293df705bd3e6adf44567ec67535334a7833 100644
--- a/lib/internal/Magento/Framework/Module/Test/Unit/StatusTest.php
+++ b/lib/internal/Magento/Framework/Module/Test/Unit/StatusTest.php
@@ -26,11 +26,6 @@ class StatusTest extends \PHPUnit_Framework_TestCase
      */
     private $writer;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cleanup;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -51,14 +46,12 @@ class StatusTest extends \PHPUnit_Framework_TestCase
         $this->loader = $this->getMock('Magento\Framework\Module\ModuleList\Loader', [], [], '', false);
         $this->moduleList = $this->getMock('Magento\Framework\Module\ModuleList', [], [], '', false);
         $this->writer = $this->getMock('Magento\Framework\App\DeploymentConfig\Writer', [], [], '', false);
-        $this->cleanup = $this->getMock('Magento\Framework\App\State\Cleanup', [], [], '', false);
         $this->conflictChecker = $this->getMock('Magento\Framework\Module\ConflictChecker', [], [], '', false);
         $this->dependencyChecker = $this->getMock('Magento\Framework\Module\DependencyChecker', [], [], '', false);
         $this->object = new Status(
             $this->loader,
             $this->moduleList,
             $this->writer,
-            $this->cleanup,
             $this->conflictChecker,
             $this->dependencyChecker
         );
@@ -95,13 +88,13 @@ class StatusTest extends \PHPUnit_Framework_TestCase
             ));
         $result = $this->object->checkConstraints(true, ['Module_Foo' => '', 'Module_Bar' => ''], [], false);
         $expect = [
-            'Cannot enable Module_Foo, depending on disabled modules:',
+            'Cannot enable Module_Foo because it depends on disabled modules:',
             "Module_Baz: Module_Foo->Module_Baz",
-            'Cannot enable Module_Bar, depending on disabled modules:',
+            'Cannot enable Module_Bar because it depends on disabled modules:',
             "Module_Baz: Module_Bar->Module_Baz",
-            'Cannot enable Module_Foo, conflicting with other modules:',
+            'Cannot enable Module_Foo because it conflicts with other modules:',
             "Module_Bar",
-            'Cannot enable Module_Bar, conflicting with other modules:',
+            'Cannot enable Module_Bar because it conflicts with other modules:',
             "Module_Foo",
         ];
         $this->assertEquals($expect, $result);
@@ -124,9 +117,9 @@ class StatusTest extends \PHPUnit_Framework_TestCase
         $expect = [
             'Cannot enable Module_Foo',
             'Cannot enable Module_Bar',
-            'Cannot enable Module_Foo, conflicting with other modules:',
+            'Cannot enable Module_Foo because it conflicts with other modules:',
             "Module_Bar",
-            'Cannot enable Module_Bar, conflicting with other modules:',
+            'Cannot enable Module_Bar because it conflicts with other modules:',
             "Module_Foo",
         ];
         $this->assertEquals($expect, $result);
@@ -153,9 +146,9 @@ class StatusTest extends \PHPUnit_Framework_TestCase
             ));
         $result = $this->object->checkConstraints(false, ['Module_Foo' => '', 'Module_Bar' => '']);
         $expect = [
-            'Cannot disable Module_Foo, modules depending on it:',
+            'Cannot disable Module_Foo because modules depend on it:',
             "Module_Baz: Module_Baz->Module_Foo",
-            'Cannot disable Module_Bar, modules depending on it:',
+            'Cannot disable Module_Bar because modules depend on it:',
             "Module_Baz: Module_Baz->Module_Bar",
         ];
         $this->assertEquals($expect, $result);
@@ -171,8 +164,6 @@ class StatusTest extends \PHPUnit_Framework_TestCase
         $expectedModules = ['Module_Foo' => 1, 'Module_Bar' => 1, 'Module_Baz' => 0];
         $this->writer->expects($this->once())->method('saveConfig')
             ->with([ConfigFilePool::APP_CONFIG => ['modules' => $expectedModules]]);
-        $this->cleanup->expects($this->once())->method('clearCaches');
-        $this->cleanup->expects($this->once())->method('clearCodeGeneratedFiles');
         $this->object->setIsEnabled(true, ['Module_Foo', 'Module_Bar']);
     }
 
diff --git a/lib/internal/Magento/Framework/View/Element/BlockFactory.php b/lib/internal/Magento/Framework/View/Element/BlockFactory.php
index 8832e6e40bb890555a14ca090d48a841ef1e537c..08f66289fb1082e5712e97c53fc8f2cd8558d8bd 100644
--- a/lib/internal/Magento/Framework/View/Element/BlockFactory.php
+++ b/lib/internal/Magento/Framework/View/Element/BlockFactory.php
@@ -42,7 +42,7 @@ class BlockFactory
         $blockName = ltrim($blockName, '\\');
         $block = $this->objectManager->create($blockName, $arguments);
         if (!$block instanceof BlockInterface) {
-            throw new \LogicException($blockName . ' does not implemented BlockInterface');
+            throw new \LogicException($blockName . ' does not implement BlockInterface');
         }
         if ($block instanceof Template) {
             $block->setTemplateContext($block);
diff --git a/setup/config/application.config.php b/setup/config/application.config.php
index 296854b1141211c1575e52fd11cd4f47c638d587..6bda9ee81bcb49d418ce8971ff28bf3c5f875877 100644
--- a/setup/config/application.config.php
+++ b/setup/config/application.config.php
@@ -18,7 +18,7 @@ return [
             __DIR__ . '/autoload/{,*.}{global,local}.php',
         ],
     ],
-    'listeners' => ['Magento\Setup\Mvc\Bootstrap\InitParamListener', 'Magento\Setup\Mvc\Console\RouteListener'],
+    'listeners' => ['Magento\Setup\Mvc\Bootstrap\InitParamListener'],
     'service_manager' => [
         'factories' => [
             InitParamListener::BOOTSTRAP_PARAM => 'Magento\Setup\Mvc\Bootstrap\InitParamListener',
diff --git a/setup/config/di.config.php b/setup/config/di.config.php
index b6bd0b18ae50dd11e50e0928a619fc1d4c626931..8d0f258ba828764481e37cc435a4fbddddc63cff 100644
--- a/setup/config/di.config.php
+++ b/setup/config/di.config.php
@@ -20,7 +20,6 @@ return [
             'Magento\Setup\Controller\CreateAdminAccount',
             'Magento\Setup\Controller\Install',
             'Magento\Setup\Controller\Success',
-            'Magento\Setup\Controller\ConsoleController',
             'Magento\Setup\Controller\Modules',
         ],
         'instance' => [
diff --git a/setup/config/router.config.php b/setup/config/router.config.php
index 817ed642dd515824dd487d8ad57a3be0a890b26f..1a16b1c7d1cfa3f834d55f59ca96fa3b015e6fb0 100644
--- a/setup/config/router.config.php
+++ b/setup/config/router.config.php
@@ -4,7 +4,6 @@
  * See COPYING.txt for license details.
  */
 
-use Magento\Setup\Controller\ConsoleController;
 
 return [
     'router' => [
@@ -36,5 +35,4 @@ return [
             ],
         ],
     ],
-    'console' => ['router' => ['routes' => ConsoleController::getRouterConfig()]],
 ];
diff --git a/setup/index.php b/setup/index.php
index 7f06ced03ba339d9c93f355ebb048a9bcc7c36c0..7c7b069afc31cd45bff2c2e2cf69d7fbc37c877c 100644
--- a/setup/index.php
+++ b/setup/index.php
@@ -4,13 +4,15 @@
  * See COPYING.txt for license details.
  */
 
+if (PHP_SAPI == 'cli') {
+    echo "You cannot run this from the command line." . PHP_EOL .
+        "Run \"php bin/magento\" instead." . PHP_EOL;
+    exit(1);
+}
 try {
     require __DIR__ . '/../app/bootstrap.php';
 } catch (\Exception $e) {
-    if (PHP_SAPI == 'cli') {
-        echo 'Autoload error: ' . $e->getMessage();
-    } else {
-        echo <<<HTML
+    echo <<<HTML
 <div style="font:12px/1.35em arial, helvetica, sans-serif;">
     <div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
         <h3 style="margin:0;font-size:1.7em;font-weight:normal;text-transform:none;text-align:left;color:#2f2f2f;">
@@ -19,7 +21,6 @@ try {
     <p>{$e->getMessage()}</p>
 </div>
 HTML;
-    }
     exit(1);
 }
 \Zend\Mvc\Application::init(require __DIR__ . '/config/application.config.php')->run();
diff --git a/setup/src/Magento/Setup/Console/Command/AbstractMaintenanceCommand.php b/setup/src/Magento/Setup/Console/Command/AbstractMaintenanceCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..fab2e492b31e8dcebdfab023fc8f40612e19e493
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/AbstractMaintenanceCommand.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Magento\Framework\App\MaintenanceMode;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+abstract class AbstractMaintenanceCommand extends AbstractSetupCommand
+{
+    /**
+     * Names of input option
+     */
+    const INPUT_KEY_IP = 'ip';
+
+    /**
+     * @var MaintenanceMode $maintenanceMode
+     */
+    protected $maintenanceMode;
+
+    /**
+     * Constructor
+     *
+     * @param MaintenanceMode $maintenanceMode
+     */
+    public function __construct(MaintenanceMode $maintenanceMode)
+    {
+        $this->maintenanceMode = $maintenanceMode;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $options = [
+            new InputOption(
+                self::INPUT_KEY_IP,
+                null,
+                InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
+                'Allowed IP addresses'
+            ),
+        ];
+        $this->setDefinition($options);
+        parent::configure();
+    }
+
+    /**
+     * Get maintenance mode to set
+     *
+     * @return bool
+     */
+    abstract protected function isEnable();
+
+    /**
+     * Get display string after mode is set
+     *
+     * @return string
+     */
+    abstract protected function getDisplayString();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $addresses = $input->getOption(self::INPUT_KEY_IP);
+        $this->maintenanceMode->set($this->isEnable());
+        $output->writeln($this->getDisplayString());
+
+        if (!empty($addresses)) {
+            $addresses = implode(',', $addresses);
+            $addresses = ('none' == $addresses) ? '' : $addresses;
+            $this->maintenanceMode->setAddresses($addresses);
+            $output->writeln(
+                '<info>Set exempt IP-addresses: ' . (implode(', ', $this->maintenanceMode->getAddressInfo()) ?: 'none')
+                . '</info>'
+            );
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/AbstractModuleCommand.php b/setup/src/Magento/Setup/Console/Command/AbstractModuleCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..9777b233790617c6a2ad3d9b9941069b3d93ce82
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/AbstractModuleCommand.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Magento\Setup\Model\ObjectManagerProvider;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Abstract class for Enable and Disable commands to consolidate common logic
+ */
+abstract class AbstractModuleCommand extends AbstractSetupCommand
+{
+    /**
+     * Names of input arguments or options
+     */
+    const INPUT_KEY_MODULES = 'module';
+    const INPUT_KEY_ALL = 'all';
+    const INPUT_KEY_FORCE = 'force';
+    const INPUT_KEY_CLEAR_STATIC_CONTENT = 'clear-static-content';
+
+    /**
+     * Object manager provider
+     *
+     * @var ObjectManagerProvider
+     */
+    private $objectManagerProvider;
+
+    /**
+     * Inject dependencies
+     *
+     * @param ObjectManagerProvider $objectManagerProvider
+     */
+    public function __construct(ObjectManagerProvider $objectManagerProvider)
+    {
+        $this->objectManagerProvider = $objectManagerProvider;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setDefinition([
+                new InputArgument(
+                    self::INPUT_KEY_MODULES,
+                    InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
+                    'Name of the module'
+                ),
+                new InputOption(
+                    self::INPUT_KEY_CLEAR_STATIC_CONTENT,
+                    'c',
+                    InputOption::VALUE_NONE,
+                    'Clear generated static view files. Necessary, if the module(s) have static view files'
+                ),
+                new InputOption(
+                    self::INPUT_KEY_FORCE,
+                    'f',
+                    InputOption::VALUE_NONE,
+                    'Bypass dependencies check'
+                ),
+                new InputOption(
+                    self::INPUT_KEY_ALL,
+                    null,
+                    InputOption::VALUE_NONE,
+                    ($this->isEnable() ? 'Enable' : 'Disable') . ' all modules'
+                ),
+            ]);
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $isEnable = $this->isEnable();
+        if ($input->getOption(self::INPUT_KEY_ALL)) {
+            /** @var \Magento\Framework\Module\FullModuleList $fullModulesList */
+            $fullModulesList = $this->objectManagerProvider->get()->get('Magento\Framework\Module\FullModuleList');
+            $modules = $fullModulesList->getNames();
+        } else {
+            $modules = $input->getArgument(self::INPUT_KEY_MODULES);
+        }
+        if (empty($modules)) {
+            throw new \InvalidArgumentException(
+                'No modules specified. Specify a space-separated list of modules or use the --all option'
+            );
+        }
+        /**
+         * @var \Magento\Framework\Module\Status $status
+         */
+        $status = $this->objectManagerProvider->get()->get('Magento\Framework\Module\Status');
+        $modulesToChange = $status->getModulesToChange($isEnable, $modules);
+        if (!empty($modulesToChange)) {
+            $force = $input->getOption(self::INPUT_KEY_FORCE);
+            if (!$force) {
+                $constraints = $status->checkConstraints($isEnable, $modulesToChange);
+                if ($constraints) {
+                    $output->writeln(
+                        "<error>Unable to change status of modules because of the following constraints:</error>"
+                    );
+                    $output->writeln('<error>' . implode("\n", $constraints) . '</error>');
+                    return;
+                }
+            }
+            $status->setIsEnabled($isEnable, $modulesToChange);
+            if ($isEnable) {
+                $output->writeln('<info>The following modules have been enabled:</info>');
+                $output->writeln('<info>- ' . implode("\n- ", $modulesToChange) . '</info>');
+                $output->writeln('');
+                $output->writeln(
+                    '<info>To make sure that the enabled modules are properly registered,'
+                    . " run 'setup:upgrade'.</info>"
+                );
+            } else {
+                $output->writeln('<info>The following modules have been disabled:</info>');
+                $output->writeln('<info>- ' . implode("\n- ", $modulesToChange) . '</info>');
+                $output->writeln('');
+            }
+            $this->cleanup($input, $output);
+            if ($force) {
+                $output->writeln(
+                    '<error>Alert: You used the --force option.'
+                    . ' As a result, modules might not function properly.</error>'
+                );
+            }
+        } else {
+            $output->writeln('<info>No modules were changed.</info>');
+        }
+    }
+
+    /**
+     * Is it "enable" or "disable" command
+     *
+     * @return bool
+     */
+    abstract protected function isEnable();
+
+    /**
+     * Cleanup after updated modules status
+     *
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return void
+     */
+    private function cleanup(InputInterface $input, OutputInterface $output)
+    {
+        $objectManager = $this->objectManagerProvider->get();
+        /** @var \Magento\Framework\App\Cache $cache */
+        $cache = $objectManager->get('Magento\Framework\App\Cache');
+        $cache->clean();
+        $output->writeln('Cache cleared successfully.');
+        /** @var \Magento\Framework\App\State\CleanupFiles $cleanupFiles */
+        $cleanupFiles = $objectManager->get('Magento\Framework\App\State\CleanupFiles');
+        $cleanupFiles->clearCodeGeneratedClasses();
+        $output->writeln('Generated classes cleared successfully.');
+        if ($input->getOption(self::INPUT_KEY_CLEAR_STATIC_CONTENT)) {
+            $cleanupFiles->clearMaterializedViewFiles();
+            $output->writeln('Generated static view files cleared successfully.');
+        } else {
+            $output->writeln(
+                '<error>Alert: Generated static view files were not cleared.'
+                . ' You can clear them using the --' . self::INPUT_KEY_CLEAR_STATIC_CONTENT . ' option.'
+                . ' Failure to clear static view files might cause display issues in the Admin and storefront.'
+            );
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php b/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b8975c02de354a3b9f94cd8763ce934429a4559
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/AbstractSetupCommand.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Magento\Setup\Mvc\Bootstrap\InitParamListener;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * An abstract class for all Magento Setup command.
+ * It adds InitParamListener's magento_init_params option to all setup command.
+ */
+abstract class AbstractSetupCommand extends Command
+{
+    /**
+     * Initialize basic Magento Setup command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->addOption(
+            InitParamListener::BOOTSTRAP_PARAM,
+            null,
+            InputOption::VALUE_REQUIRED,
+            'Add to any command to customize Magento initialization parameters' . PHP_EOL .
+            "For example: 'MAGE_MODE=developer&MAGE_DIRS[base][path]" .
+            "=/var/www/example.com&MAGE_DIRS[cache][path]=/var/tmp/cache'"
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php b/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..3dd27d09e0c5f080e697eff9867f49e434495a48
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/AdminUserCreateCommand.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Setup\Model\AdminAccount;
+use Magento\Setup\Model\ConsoleLogger;
+use Magento\Setup\Model\InstallerFactory;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class AdminUserCreateCommand extends AbstractSetupCommand
+{
+    /**
+     * @var InstallerFactory
+     */
+    private $installerFactory;
+
+    /**
+     * @param InstallerFactory $installerFactory
+     */
+    public function __construct(InstallerFactory $installerFactory)
+    {
+        $this->installerFactory = $installerFactory;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('admin:user:create')
+            ->setDescription('Creates admin user')
+            ->setDefinition($this->getOptionsList());
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $errors = $this->validate($input);
+        if ($errors) {
+            throw new \InvalidArgumentException(implode("\n", $errors));
+        }
+        $installer = $this->installerFactory->create(new ConsoleLogger($output));
+        $installer->installAdminUser($input->getOptions());
+        $output->writeln('<info>Created admin user ' . $input->getOption(AdminAccount::KEY_USER) . '</info>');
+    }
+
+    /**
+     * Get list of arguments for the command
+     *
+     * @return InputOption[]
+     */
+    public function getOptionsList()
+    {
+        return [
+            new InputOption(AdminAccount::KEY_USER, null, InputOption::VALUE_REQUIRED, 'Admin user'),
+            new InputOption(AdminAccount::KEY_PASSWORD, null, InputOption::VALUE_REQUIRED, 'Admin password'),
+            new InputOption(AdminAccount::KEY_EMAIL, null, InputOption::VALUE_REQUIRED, 'Admin email'),
+            new InputOption(AdminAccount::KEY_FIRST_NAME, null, InputOption::VALUE_REQUIRED, 'Admin first name'),
+            new InputOption(AdminAccount::KEY_LAST_NAME, null, InputOption::VALUE_REQUIRED, 'Admin last name'),
+        ];
+    }
+
+    /**
+     * Check if all admin options are provided
+     *
+     * @param InputInterface $input
+     * @return string[]
+     */
+    public function validate(InputInterface $input)
+    {
+        $errors = [];
+        $required = [
+            AdminAccount::KEY_USER,
+            AdminAccount::KEY_PASSWORD,
+            AdminAccount::KEY_EMAIL,
+            AdminAccount::KEY_FIRST_NAME,
+            AdminAccount::KEY_LAST_NAME,
+        ];
+        foreach ($required as $key) {
+            if (!$input->getOption($key)) {
+                $errors[] = 'Missing option ' . $key;
+            }
+        }
+        return $errors;
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php
index 0a95ba642a39c1eaba8d578889b304afb88116be..6a86ee2ce9a8ab85b92442a104cf17c71e516ffc 100644
--- a/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/ConfigSetCommand.php
@@ -9,11 +9,10 @@ namespace Magento\Setup\Console\Command;
 use Magento\Framework\App\DeploymentConfig;
 use Magento\Framework\Module\ModuleList;
 use Magento\Setup\Model\ConfigModel;
-use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 
-class ConfigSetCommand extends Command
+class ConfigSetCommand extends AbstractSetupCommand
 {
     /**
      * @var ConfigModel
@@ -63,7 +62,7 @@ class ConfigSetCommand extends Command
             ->setDescription('Sets deployment configuration')
             ->setDefinition($options);
 
-        $this->ignoreValidationErrors();
+        parent::configure();
     }
 
     /**
@@ -84,7 +83,7 @@ class ConfigSetCommand extends Command
                 $dialog = $this->getHelperSet()->get('dialog');
                 if (!$dialog->askConfirmation(
                     $output,
-                    '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y|n]</question>'
+                    '<question>Overwrite the existing configuration for ' . $option->getName() . '?[Y/n]</question>'
                 )) {
                     $inputOptions[$option->getName()] = null;
                 }
diff --git a/setup/src/Magento/Setup/Console/Command/DbDataUpgradeCommand.php b/setup/src/Magento/Setup/Console/Command/DbDataUpgradeCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..b915fa2a83067e27757b3d24ba884edac8c671b3
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/DbDataUpgradeCommand.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Framework\App\DeploymentConfig;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\ConsoleLogger;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for install and update of data in DB
+ */
+class DbDataUpgradeCommand extends AbstractSetupCommand
+{
+    /**
+     * Factory to create installer
+     *
+     * @var InstallerFactory
+     */
+    private $installFactory;
+
+    /**
+     * Deployment configuration
+     *
+     * @var DeploymentConfig
+     */
+    private $deploymentConfig;
+
+    /**
+     * Inject dependencies
+     *
+     * @param InstallerFactory $installFactory
+     * @param DeploymentConfig $deploymentConfig
+     */
+    public function __construct(InstallerFactory $installFactory, DeploymentConfig $deploymentConfig)
+    {
+        $this->installFactory = $installFactory;
+        $this->deploymentConfig = $deploymentConfig;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('setup:db-data:upgrade')->setDescription('Installs and upgrades data in the DB');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$this->deploymentConfig->isAvailable()) {
+            $output->writeln("<info>No information is available: the application is not installed.</info>");
+            return;
+        }
+        $installer = $this->installFactory->create(new ConsoleLogger($output));
+        $installer->installDataFixtures();
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/DbSchemaUpgradeCommand.php b/setup/src/Magento/Setup/Console/Command/DbSchemaUpgradeCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc3f5bd9888acbd89a44216d1f144650e6f4403d
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/DbSchemaUpgradeCommand.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Framework\App\DeploymentConfig;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\ConsoleLogger;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for install and update of DB schema
+ */
+class DbSchemaUpgradeCommand extends AbstractSetupCommand
+{
+    /**
+     * Factory to create installer
+     *
+     * @var InstallerFactory
+     */
+    private $installFactory;
+
+    /**
+     * Deployment configuration
+     *
+     * @var DeploymentConfig
+     */
+    private $deploymentConfig;
+
+    /**
+     * Inject dependencies
+     *
+     * @param InstallerFactory $installFactory
+     * @param DeploymentConfig $deploymentConfig
+     */
+    public function __construct(InstallerFactory $installFactory, DeploymentConfig $deploymentConfig)
+    {
+        $this->installFactory = $installFactory;
+        $this->deploymentConfig = $deploymentConfig;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('setup:db-schema:upgrade')->setDescription('Installs and upgrades the DB schema');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$this->deploymentConfig->isAvailable()) {
+            $output->writeln("<info>No information is available: the application is not installed.</info>");
+            return;
+        }
+        $installer = $this->installFactory->create(new ConsoleLogger($output));
+        $installer->installSchema();
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/DbStatusCommand.php b/setup/src/Magento/Setup/Console/Command/DbStatusCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d996aec45e7e2a928a44a14ce237557fc029a10
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/DbStatusCommand.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Composer\Package\Version\VersionParser;
+use Magento\Framework\App\DeploymentConfig;
+use Magento\Framework\Module\DbVersionInfo;
+use Magento\Setup\Model\ObjectManagerProvider;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for checking if DB version is in sync with the code base version
+ */
+class DbStatusCommand extends AbstractSetupCommand
+{
+    /**
+     * Object manager provider
+     *
+     * @var ObjectManagerProvider
+     */
+    private $objectManagerProvider;
+
+    /**
+     * Deployment configuration
+     *
+     * @var DeploymentConfig
+     */
+    private $deploymentConfig;
+
+    /**
+     * Inject dependencies
+     *
+     * @param ObjectManagerProvider $objectManagerProvider
+     * @param DeploymentConfig $deploymentConfig
+     */
+    public function __construct(ObjectManagerProvider $objectManagerProvider, DeploymentConfig $deploymentConfig)
+    {
+        $this->objectManagerProvider = $objectManagerProvider;
+        $this->deploymentConfig = $deploymentConfig;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('setup:db:status')
+            ->setDescription('Checks if update of DB schema or data is required');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$this->deploymentConfig->isAvailable()) {
+            $output->writeln("<info>No information is available: the application is not installed.</info>");
+            return;
+        }
+        /** @var DbVersionInfo $dbVersionInfo */
+        $dbVersionInfo = $this->objectManagerProvider->get()
+            ->get('Magento\Framework\Module\DbVersionInfo');
+        $outdated = $dbVersionInfo->getDbVersionErrors();
+        if (!empty($outdated)) {
+            $output->writeln("<info>The module code base doesn't match the DB schema and data.</info>");
+            $versionParser = new VersionParser();
+            $codebaseUpdateNeeded = false;
+            foreach ($outdated as $row) {
+                if (!$codebaseUpdateNeeded && $row[DbVersionInfo::KEY_CURRENT] !== 'none') {
+                    // check if module code base update is needed
+                    $currentVersion = $versionParser->parseConstraints($row[DbVersionInfo::KEY_CURRENT]);
+                    $requiredVersion = $versionParser->parseConstraints('>' . $row[DbVersionInfo::KEY_REQUIRED]);
+                    if ($requiredVersion->matches($currentVersion)) {
+                        $codebaseUpdateNeeded = true;
+                    };
+                }
+                $output->writeln(sprintf(
+                    "<info>%20s %10s: %11s  ->  %-11s</info>",
+                    $row[DbVersionInfo::KEY_MODULE],
+                    $row[DbVersionInfo::KEY_TYPE],
+                    $row[DbVersionInfo::KEY_CURRENT],
+                    $row[DbVersionInfo::KEY_REQUIRED]
+                ));
+            }
+            if ($codebaseUpdateNeeded) {
+                $output->writeln(
+                    '<info>Some modules use code versions newer or older than the database. ' .
+                    "First update the module code, then run 'setup:upgrade'.</info>"
+                );
+            } else {
+                $output->writeln("<info>Run 'setup:upgrade' to update your DB schema and data.</info>");
+            }
+        } else {
+            $output->writeln('<info>All modules are up to date.</info>');
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/InfoCurrencyListCommand.php b/setup/src/Magento/Setup/Console/Command/InfoCurrencyListCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e2aba2b3ab857521cbffda4cdcd20b09d94b0af
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InfoCurrencyListCommand.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Magento\Setup\Model\Lists;
+
+/**
+ * Command prints list of available currencies
+ */
+class InfoCurrencyListCommand extends Command
+{
+    /**
+     * List model provides lists of available options for currency, language locales, timezones
+     *
+     * @var Lists
+     */
+    private $lists;
+
+    /**
+     * @param Lists $lists
+     */
+    public function __construct(Lists $lists)
+    {
+        $this->lists = $lists;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('info:currency:list')
+            ->setDescription('Prints list of available currencies');
+
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        foreach ($this->lists->getCurrencyList() as $key => $currency) {
+            $output->writeln($key . ' => ' . $currency);
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/InfoLanguageListCommand.php b/setup/src/Magento/Setup/Console/Command/InfoLanguageListCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..6066baeadda4fb8f77bf45a3b893d33406d99894
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InfoLanguageListCommand.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Magento\Setup\Model\Lists;
+
+/**
+ * Command prints list of available language locales
+ */
+class InfoLanguageListCommand extends Command
+{
+    /**
+     * List model provides lists of available options for currency, language locales, timezones
+     *
+     * @var Lists
+     */
+    private $lists;
+
+    /**
+     * @param Lists $lists
+     */
+    public function __construct(Lists $lists)
+    {
+        $this->lists = $lists;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('info:language:list')
+            ->setDescription('Prints list of available language locales');
+
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        foreach ($this->lists->getLocaleList() as $key => $locale) {
+            $output->writeln($key . ' => ' . $locale);
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/InfoTimezoneListCommand.php b/setup/src/Magento/Setup/Console/Command/InfoTimezoneListCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cb013b4dfa07041a5c95f40f581a81ca9eeb735
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InfoTimezoneListCommand.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Magento\Setup\Model\Lists;
+
+/**
+ * Command prints list of available timezones
+ */
+class InfoTimezoneListCommand extends Command
+{
+    /**
+     * List model provides lists of available options for currency, language locales, timezones
+     *
+     * @var Lists
+     */
+    private $lists;
+
+    /**
+     * @param Lists $lists
+     */
+    public function __construct(Lists $lists)
+    {
+        $this->lists = $lists;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('info:timezone:list')
+            ->setDescription('Prints list of available timezones');
+
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        foreach ($this->lists->getTimezoneList() as $key => $timezone) {
+            $output->writeln($key . ' => ' . $timezone);
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/InstallCommand.php b/setup/src/Magento/Setup/Console/Command/InstallCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..2601e45b7aa1e5eb9fa960670e7055e7c9ce433f
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InstallCommand.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\ConsoleLogger;
+use Symfony\Component\Console\Input\InputOption;
+use Magento\Setup\Model\ConfigModel;
+
+/**
+ * Command to install Magento application
+ */
+class InstallCommand extends AbstractSetupCommand
+{
+    /**
+     * Parameter indicating command whether to cleanup database in the install routine
+     */
+    const INPUT_KEY_CLEANUP_DB = 'cleanup_database';
+
+    /**
+     * Parameter to specify an order_increment_prefix
+     */
+    const INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX = 'sales_order_increment_prefix';
+
+    /**
+     * Parameter indicating command whether to install Sample Data
+     */
+    const INPUT_KEY_USE_SAMPLE_DATA = 'use_sample_data';
+
+    /**
+     * Installer service factory
+     *
+     * @var InstallerFactory
+     */
+    private $installerFactory;
+
+    /**
+     * @var ConfigModel
+     */
+    protected $configModel;
+
+    /**
+     * @var InstallStoreConfigurationCommand
+     */
+    protected $userConfig;
+
+    /**
+     * @var AdminUserCreateCommand
+     */
+    protected $adminUser;
+
+    /**
+     * Constructor
+     *
+     * @param InstallerFactory $installerFactory
+     * @param ConfigModel $configModel
+     * @param InstallStoreConfigurationCommand $userConfig
+     * @param AdminUserCreateCommand $adminUser
+     */
+    public function __construct(
+        InstallerFactory $installerFactory,
+        ConfigModel $configModel,
+        InstallStoreConfigurationCommand $userConfig,
+        AdminUserCreateCommand $adminUser
+    ) {
+        $this->installerFactory = $installerFactory;
+        $this->configModel = $configModel;
+        $this->userConfig = $userConfig;
+        $this->adminUser = $adminUser;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $inputOptions = $this->configModel->getAvailableOptions();
+        $inputOptions = array_merge($inputOptions, $this->userConfig->getOptionsList());
+        $inputOptions = array_merge($inputOptions, $this->adminUser->getOptionsList());
+        $inputOptions = array_merge($inputOptions, [
+            new InputOption(
+                self::INPUT_KEY_CLEANUP_DB,
+                null,
+                InputOption::VALUE_NONE,
+                'Cleanup the database before installation'
+            ),
+            new InputOption(
+                self::INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Sales order number prefix'
+            ),
+            new InputOption(
+                self::INPUT_KEY_USE_SAMPLE_DATA,
+                null,
+                InputOption::VALUE_NONE,
+                'Use sample data'
+            )
+        ]);
+        $this->setName('setup:install')
+            ->setDescription('Installs Magento Application')
+            ->setDefinition($inputOptions);
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $consoleLogger = new ConsoleLogger($output);
+        $installer = $this->installerFactory->create($consoleLogger);
+        $installer->install($input->getOptions());
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function initialize(InputInterface $input, OutputInterface $output)
+    {
+        $inputOptions = $input->getOptions();
+
+        $configOptionsToValidate = [];
+        foreach ($this->configModel->getAvailableOptions() as $option) {
+            if (array_key_exists($option->getName(), $inputOptions)) {
+                $configOptionsToValidate[$option->getName()] = $inputOptions[$option->getName()];
+            }
+        }
+        $errors = $this->configModel->validate($configOptionsToValidate);
+        $errors = array_merge($errors, $this->adminUser->validate($input));
+        if (!empty($errors)) {
+            foreach ($errors as $error) {
+                $output->writeln("<error>$error</error>");
+            }
+            throw new \InvalidArgumentException('Parameters validation is failed');
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae4eb99fa86c4c504ac4ab4d07ecb09ee1363173
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Setup\Model\ConsoleLogger;
+use Magento\Framework\App\DeploymentConfig;
+use Magento\Setup\Model\InstallerFactory;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Magento\Setup\Model\StoreConfigurationDataMapper;
+
+class InstallStoreConfigurationCommand extends AbstractSetupCommand
+{
+    /**
+     * @var InstallerFactory
+     */
+    private $installerFactory;
+
+    /**
+     * Deployment configuration
+     *
+     * @var DeploymentConfig
+     */
+    private $deploymentConfig;
+
+    /**
+     * Inject dependencies
+     *
+     * @param InstallerFactory $installerFactory
+     * @param DeploymentConfig $deploymentConfig
+     */
+    public function __construct(
+        InstallerFactory $installerFactory,
+        DeploymentConfig $deploymentConfig
+    ) {
+        $this->installerFactory = $installerFactory;
+        $this->deploymentConfig = $deploymentConfig;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('setup:store-config:set')
+            ->setDescription('Installs store configuration')
+            ->setDefinition($this->getOptionsList());
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$this->deploymentConfig->isAvailable()) {
+            $output->writeln(
+                "<info>Store settings can't be saved because the Magento application is not installed.</info>"
+            );
+            return;
+        }
+        $installer = $this->installerFactory->create(new ConsoleLogger($output));
+        $installer->installUserConfig($input->getOptions());
+    }
+
+    /**
+     * Get list of options for the command
+     *
+     * @return InputOption[]
+     */
+    public function getOptionsList()
+    {
+        return [
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_BASE_URL,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'URL the store is supposed to be available at'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_LANGUAGE,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Default language code'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_TIMEZONE,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Default time zone code'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_CURRENCY,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Default currency code'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_USE_SEF_URL,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Use rewrites'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_IS_SECURE,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Use secure URLs. Enable this option only if SSL is available.'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_BASE_URL_SECURE,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Base URL for SSL connection'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Run admin interface with SSL'
+            ),
+            new InputOption(
+                StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY,
+                null,
+                InputOption::VALUE_REQUIRED,
+                'Whether to use a "security key" feature in Magento Admin URLs and forms'
+            ),
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/MaintenanceAllowIpsCommand.php b/setup/src/Magento/Setup/Console/Command/MaintenanceAllowIpsCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..3aad4d09d16036e24d3dc9265cf0feca8ec4ba70
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/MaintenanceAllowIpsCommand.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Framework\App\MaintenanceMode;
+use Magento\Framework\Module\ModuleList;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for setting allowed IPs in maintenance mode
+ */
+class MaintenanceAllowIpsCommand extends AbstractSetupCommand
+{
+    /**
+     * Names of input arguments or options
+     */
+    const INPUT_KEY_IP = 'ip';
+    const INPUT_KEY_NONE = 'none';
+
+    /**
+     * @var MaintenanceMode $maintenanceMode
+     */
+    private $maintenanceMode;
+
+    /**
+     * Constructor
+     *
+     * @param MaintenanceMode $maintenanceMode
+     */
+    public function __construct(MaintenanceMode $maintenanceMode)
+    {
+        $this->maintenanceMode = $maintenanceMode;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $arguments = [
+            new InputArgument(
+                self::INPUT_KEY_IP,
+                InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
+                'Allowed IP addresses'
+            ),
+        ];
+        $options = [
+            new InputOption(
+                self::INPUT_KEY_NONE,
+                null,
+                InputOption::VALUE_NONE,
+                'Clear allowed IP addresses'
+            ),
+        ];
+        $this->setName('maintenance:allow-ips')
+            ->setDescription('Sets maintenance mode exempt IPs')
+            ->setDefinition(array_merge($arguments, $options));
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (!$input->getOption(self::INPUT_KEY_NONE)) {
+            $addresses = $input->getArgument(self::INPUT_KEY_IP);
+            if (!empty($addresses)) {
+                $this->maintenanceMode->setAddresses(implode(',', $addresses));
+                $output->writeln(
+                    '<info>Set exempt IP-addresses: ' . implode(', ', $this->maintenanceMode->getAddressInfo()) .
+                    '</info>'
+                );
+            }
+        } else {
+            $this->maintenanceMode->setAddresses('');
+            $output->writeln('<info>Set exempt IP-addresses: none</info>');
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/MaintenanceDisableCommand.php b/setup/src/Magento/Setup/Console/Command/MaintenanceDisableCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..988c0628c4d86d02890f322b10af740d9ccd858b
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/MaintenanceDisableCommand.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+/**
+ * Command for disabling maintenance mode
+ */
+class MaintenanceDisableCommand extends AbstractMaintenanceCommand
+{
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('maintenance:disable')->setDescription('Disables maintenance mode');
+        parent::configure();
+    }
+
+    /**
+     * Disable maintenance mode
+     *
+     * @return bool
+     */
+    protected function isEnable()
+    {
+        return false;
+    }
+
+    /**
+     * Get disabled maintenance mode display string
+     *
+     * @return string
+     */
+    protected function getDisplayString()
+    {
+        return '<info>Disabled maintenance mode</info>';
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/MaintenanceEnableCommand.php b/setup/src/Magento/Setup/Console/Command/MaintenanceEnableCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..85c1579ce659fed69c63f5e71de46d83acb2c14c
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/MaintenanceEnableCommand.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+/**
+ * Command for enabling maintenance mode
+ */
+class MaintenanceEnableCommand extends AbstractMaintenanceCommand
+{
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('maintenance:enable')->setDescription('Enables maintenance mode');
+        parent::configure();
+    }
+
+    /**
+     * Enable maintenance mode
+     *
+     * @return bool
+     */
+    protected function isEnable()
+    {
+        return true;
+    }
+
+    /**
+     * Get enabled maintenance mode display string
+     *
+     * @return string
+     */
+    protected function getDisplayString()
+    {
+        return '<info>Enabled maintenance mode</info>';
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/MaintenanceStatusCommand.php b/setup/src/Magento/Setup/Console/Command/MaintenanceStatusCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ff1c2f97c23f822f676973a90e2938e1bdc0a4b
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/MaintenanceStatusCommand.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Magento\Framework\App\MaintenanceMode;
+use Magento\Framework\Module\ModuleList;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for checking maintenance mode status
+ */
+class MaintenanceStatusCommand extends AbstractSetupCommand
+{
+    /**
+     * @var MaintenanceMode $maintenanceMode
+     */
+    private $maintenanceMode;
+
+    /**
+     * Constructor
+     *
+     * @param MaintenanceMode $maintenanceMode
+     */
+    public function __construct(MaintenanceMode $maintenanceMode)
+    {
+        $this->maintenanceMode = $maintenanceMode;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('maintenance:status')
+            ->setDescription('Checks maintenance mode status');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln(
+            '<info>Status: maintenance mode is ' .
+            ($this->maintenanceMode->isOn() ? 'active' : 'not active') . '</info>'
+        );
+        $addressInfo = $this->maintenanceMode->getAddressInfo();
+        $addresses = implode(', ', $addressInfo);
+        $output->writeln('<info>List of exempt IP-addresses: ' . ($addresses ? $addresses : 'none') . '</info>');
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/ModuleDisableCommand.php b/setup/src/Magento/Setup/Console/Command/ModuleDisableCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e12c46331fca12d966f9bc247b8e9fd4840d36f
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/ModuleDisableCommand.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+/**
+ * Command for disabling list or all of modules
+ */
+class ModuleDisableCommand extends AbstractModuleCommand
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('module:disable')
+            ->setDescription('Disables specified modules');
+        parent::configure();
+    }
+
+    /**
+     * Disable modules
+     *
+     * @return bool
+     */
+    protected function isEnable()
+    {
+        return false;
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/ModuleEnableCommand.php b/setup/src/Magento/Setup/Console/Command/ModuleEnableCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..0efc1d8928aafd83fe8950a28d8ccf9b1af41224
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/ModuleEnableCommand.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+/**
+ * Command for enabling list or all of modules
+ */
+class ModuleEnableCommand extends AbstractModuleCommand
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('module:enable')
+            ->setDescription('Enables specified modules');
+        parent::configure();
+    }
+
+    /**
+     * Enable modules
+     *
+     * @return bool
+     */
+    protected function isEnable()
+    {
+        return true;
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/ModuleStatusCommand.php b/setup/src/Magento/Setup/Console/Command/ModuleStatusCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d802b17637f94495b1324ed723fc77a532ae630
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/ModuleStatusCommand.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Magento\Setup\Model\ObjectManagerProvider;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Command for displaying status of modules
+ */
+class ModuleStatusCommand extends AbstractSetupCommand
+{
+    /**
+     * Object manager provider
+     *
+     * @var ObjectManagerProvider
+     */
+    private $objectManagerProvider;
+
+    /**
+     * Inject dependencies
+     *
+     * @param ObjectManagerProvider $objectManagerProvider
+     */
+    public function __construct(ObjectManagerProvider $objectManagerProvider)
+    {
+        $this->objectManagerProvider = $objectManagerProvider;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('module:status')
+            ->setDescription('Displays status of modules');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $moduleList = $this->objectManagerProvider->get()->create('Magento\Framework\Module\ModuleList');
+        $output->writeln('<info>List of enabled modules:</info>');
+        $enabledModules = $moduleList->getNames();
+        if (count($enabledModules) === 0) {
+            $output->writeln('None');
+        } else {
+            $output->writeln(join("\n", $enabledModules));
+        }
+        $output->writeln('');
+
+        $fullModuleList = $this->objectManagerProvider->get()->create('Magento\Framework\Module\FullModuleList');
+        $output->writeln("<info>List of disabled modules:</info>");
+        $disabledModules = array_diff($fullModuleList->getNames(), $enabledModules);
+        if (count($disabledModules) === 0) {
+            $output->writeln('None');
+        } else {
+            $output->writeln(join("\n", $disabledModules));
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/UninstallCommand.php b/setup/src/Magento/Setup/Console/Command/UninstallCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..0982c6381974d08b8fbd2663b2f9ef700580697b
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/UninstallCommand.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\ConsoleLogger;
+
+class UninstallCommand extends AbstractSetupCommand
+{
+    /**
+     * @var InstallerFactory
+     */
+    private $installerFactory;
+
+    /**
+     * @param InstallerFactory $installerFactory
+     */
+    public function __construct(InstallerFactory $installerFactory)
+    {
+        $this->installerFactory = $installerFactory;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('setup:uninstall')
+            ->setDescription('Uninstalls Magento application');
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $helper = $this->getHelper('question');
+        $question = new ConfirmationQuestion('Are you sure you want to uninstall Magento?[y/N]', false);
+
+        if ($helper->ask($input, $output, $question) || !$input->isInteractive()) {
+            $installer = $this->installerFactory->create(new ConsoleLogger($output));
+            $installer->uninstall();
+        }
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c7b54bd294f1ed79d6669ed737348d718bcf4f8
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/UpgradeCommand.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Model\ConsoleLogger;
+
+/**
+ * Command for updating installed application after the code base has changed
+ */
+class UpgradeCommand extends AbstractSetupCommand
+{
+    /**
+     * Installer service factory
+     *
+     * @var InstallerFactory
+     */
+    private $installerFactory;
+
+    /**
+     * Constructor
+     *
+     * @param InstallerFactory $installerFactory
+     */
+    public function __construct(InstallerFactory $installerFactory)
+    {
+        $this->installerFactory = $installerFactory;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this->setName('setup:upgrade')
+            ->setDescription(
+                'Upgrades installed application after the code base has changed, '
+                . 'including DB schema and data'
+            );
+        parent::configure();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $installer = $this->installerFactory->create(new ConsoleLogger($output));
+        $installer->updateModulesSequence();
+        $installer->installSchema();
+        $installer->installDataFixtures();
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/CommandList.php b/setup/src/Magento/Setup/Console/CommandList.php
index 0a4f4ef8f281ac3ba882013ed070677cb5968fae..a75ed3b3226553a09390a93911b076192422c820 100644
--- a/setup/src/Magento/Setup/Console/CommandList.php
+++ b/setup/src/Magento/Setup/Console/CommandList.php
@@ -10,8 +10,6 @@ use Zend\ServiceManager\ServiceManager;
 
 /**
  * Class CommandList contains predefined list of commands for Setup
- *
- * @package Magento\Setup\Console
  */
 class CommandList
 {
@@ -40,7 +38,25 @@ class CommandList
     protected function getCommandsClasses()
     {
         return [
+            'Magento\Setup\Console\Command\AdminUserCreateCommand',
             'Magento\Setup\Console\Command\ConfigSetCommand',
+            'Magento\Setup\Console\Command\DbDataUpgradeCommand',
+            'Magento\Setup\Console\Command\DbSchemaUpgradeCommand',
+            'Magento\Setup\Console\Command\DbStatusCommand',
+            'Magento\Setup\Console\Command\InfoCurrencyListCommand',
+            'Magento\Setup\Console\Command\InfoLanguageListCommand',
+            'Magento\Setup\Console\Command\InfoTimezoneListCommand',
+            'Magento\Setup\Console\Command\InstallCommand',
+            'Magento\Setup\Console\Command\InstallStoreConfigurationCommand',
+            'Magento\Setup\Console\Command\ModuleEnableCommand',
+            'Magento\Setup\Console\Command\ModuleDisableCommand',
+            'Magento\Setup\Console\Command\ModuleStatusCommand',
+            'Magento\Setup\Console\Command\MaintenanceAllowIpsCommand',
+            'Magento\Setup\Console\Command\MaintenanceDisableCommand',
+            'Magento\Setup\Console\Command\MaintenanceEnableCommand',
+            'Magento\Setup\Console\Command\MaintenanceStatusCommand',
+            'Magento\Setup\Console\Command\UpgradeCommand',
+            'Magento\Setup\Console\Command\UninstallCommand',
         ];
     }
 
diff --git a/setup/src/Magento/Setup/Controller/ConsoleController.php b/setup/src/Magento/Setup/Controller/ConsoleController.php
deleted file mode 100644
index eb0ca1f1d1e79cd90eb74511a00aa934c9227a33..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Controller/ConsoleController.php
+++ /dev/null
@@ -1,689 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Controller;
-
-use Composer\Package\Version\VersionParser;
-use Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
-use Magento\Framework\App\MaintenanceMode;
-use Magento\Setup\Model\AdminAccount;
-use Magento\Framework\Config\ConfigOptionsList as SetupConfigOptionsList;
-use Magento\Setup\Model\ConsoleLogger;
-use Magento\Setup\Model\Installer;
-use Magento\Setup\Model\InstallerFactory;
-use Magento\Setup\Model\Lists;
-use Magento\Setup\Model\UserConfigurationDataMapper as UserConfig;
-use Magento\Setup\Mvc\Bootstrap\InitParamListener;
-use Zend\Console\Request as ConsoleRequest;
-use Zend\EventManager\EventManagerInterface;
-use Zend\Mvc\Controller\AbstractActionController;
-use Magento\Setup\Model\ObjectManagerProvider;
-use Magento\Framework\Module\DbVersionInfo;
-
-/**
- * Controller that handles all setup commands via command line interface.
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class ConsoleController extends AbstractActionController
-{
-    /**#@+
-     * Supported command types
-     */
-    const CMD_HELP = 'help';
-    const CMD_INSTALL = 'install';
-    const CMD_INSTALL_CONFIG = 'install-configuration';
-    const CMD_INSTALL_SCHEMA = 'install-schema';
-    const CMD_INSTALL_DATA = 'install-data';
-    const CMD_INSTALL_USER_CONFIG = 'install-user-configuration';
-    const CMD_INSTALL_ADMIN_USER = 'install-admin-user';
-    const CMD_UPDATE = 'update';
-    const CMD_DB_STATUS = 'db-status';
-    const CMD_UNINSTALL = 'uninstall';
-    const CMD_MAINTENANCE = 'maintenance';
-    const CMD_MODULE_ENABLE = 'module-enable';
-    const CMD_MODULE_DISABLE = 'module-disable';
-    /**#@- */
-
-    /**
-     * Help option for retrieving list of modules
-     */
-    const HELP_LIST_OF_MODULES = 'module-list';
-
-    /**
-     * Map of controller actions exposed in CLI
-     *
-     * @var string[]
-     */
-    private static $actions = [
-        self::CMD_HELP => 'help',
-        self::CMD_INSTALL => 'install',
-        self::CMD_INSTALL_SCHEMA => 'installSchema',
-        self::CMD_INSTALL_DATA => 'installData',
-        self::CMD_INSTALL_USER_CONFIG => 'installUserConfig',
-        self::CMD_INSTALL_ADMIN_USER => 'installAdminUser',
-        self::CMD_UPDATE => 'update',
-        self::CMD_DB_STATUS => 'dbStatus',
-        self::CMD_UNINSTALL => 'uninstall',
-        self::CMD_MAINTENANCE => 'maintenance',
-        self::CMD_MODULE_ENABLE => 'module',
-        self::CMD_MODULE_DISABLE => 'module',
-    ];
-
-    /**
-     * Options for "help" command
-     *
-     * @var string[]
-     */
-    private static $helpOptions = [
-        self::CMD_INSTALL,
-        self::CMD_INSTALL_SCHEMA,
-        self::CMD_INSTALL_DATA,
-        self::CMD_INSTALL_USER_CONFIG,
-        self::CMD_INSTALL_ADMIN_USER,
-        self::CMD_UPDATE,
-        self::CMD_DB_STATUS,
-        self::CMD_UNINSTALL,
-        self::CMD_MAINTENANCE,
-        self::CMD_MODULE_ENABLE,
-        self::CMD_MODULE_DISABLE,
-        UserConfig::KEY_LANGUAGE,
-        UserConfig::KEY_CURRENCY,
-        UserConfig::KEY_TIMEZONE,
-        self::HELP_LIST_OF_MODULES,
-    ];
-
-    /**
-     * Logger
-     *
-     * @var ConsoleLogger
-     */
-    private $log;
-
-    /**
-     * Options Lists
-     *
-     * @var Lists
-     */
-    private $options;
-
-    /**
-     * Installer service
-     *
-     * @var Installer
-     */
-    private $installer;
-
-    /**
-     * Object manager provider
-     *
-     * @var ObjectManagerProvider
-     */
-    private $objectManagerProvider;
-
-    /**
-     * Gets router configuration to be used in module definition
-     *
-     * @return array
-     */
-    public static function getRouterConfig()
-    {
-        $result = [];
-        $config = self::getCliConfig();
-        foreach (self::$actions as $type => $action) {
-            $result[$type] = ['options' => [
-                'route' => $config[$type]['route'],
-                'defaults' => ['controller' => __CLASS__, 'action' => $action],
-            ]];
-        }
-        return $result;
-    }
-
-    /**
-     * Gets console usage to be used in module definition
-     *
-     * @return array
-     */
-    public static function getConsoleUsage()
-    {
-        $result = ["Usage:\n"];
-        foreach (self::getCliConfig() as $cmd) {
-            $result[$cmd['usage_short']] = $cmd['usage_desc'];
-        }
-        foreach (self::$helpOptions as $type) {
-            $result[] = '    ' . ConsoleController::CMD_HELP . ' ' . $type;
-        }
-        return $result;
-    }
-
-    /**
-     * Gets command usage
-     *
-     * @return array
-     */
-    public static function getCommandUsage()
-    {
-        $result = [];
-        foreach (self::getCliConfig() as $key => $cmd) {
-            $result[$key] = $cmd['usage'];
-        }
-        return $result;
-    }
-
-    /**
-     * The CLI that this controller implements
-     *
-     * @return array
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    private static function getCliConfig()
-    {
-        $deployConfig = '--' . SetupConfigOptionsList::INPUT_KEY_DB_HOST . '='
-            . ' --' . SetupConfigOptionsList::INPUT_KEY_DB_NAME . '='
-            . ' --' . SetupConfigOptionsList::INPUT_KEY_DB_USER . '='
-            . ' --' . BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME . '='
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_DB_PASS . '=]'
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_DB_PREFIX . '=]'
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_DB_MODEL . '=]'
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_DB_INIT_STATEMENTS . '=]'
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_SESSION_SAVE . '=]'
-            . ' [--' . SetupConfigOptionsList::INPUT_KEY_ENCRYPTION_KEY . '=]'
-            . ' [--' . Installer::ENABLE_MODULES . '=]'
-            . ' [--' . Installer::DISABLE_MODULES . '=]';
-        $userConfig = '[--' . UserConfig::KEY_BASE_URL . '=]'
-            . ' [--' . UserConfig::KEY_LANGUAGE . '=]'
-            . ' [--' . UserConfig::KEY_TIMEZONE . '=]'
-            . ' [--' . UserConfig::KEY_CURRENCY . '=]'
-            . ' [--' . UserConfig::KEY_USE_SEF_URL . '=]'
-            . ' [--' . UserConfig::KEY_IS_SECURE . '=]'
-            . ' [--' . UserConfig::KEY_BASE_URL_SECURE . '=]'
-            . ' [--' . UserConfig::KEY_IS_SECURE_ADMIN . '=]'
-            . ' [--' . UserConfig::KEY_ADMIN_USE_SECURITY_KEY . '=]';
-        $adminUser = '--' . AdminAccount::KEY_USERNAME . '='
-            . ' --' . AdminAccount::KEY_PASSWORD . '='
-            . ' --' . AdminAccount::KEY_EMAIL . '='
-            . ' --' . AdminAccount::KEY_FIRST_NAME . '='
-            . ' --' . AdminAccount::KEY_LAST_NAME . '=';
-        $salesConfig = '[--' . Installer::SALES_ORDER_INCREMENT_PREFIX . '=]';
-        return [
-            self::CMD_INSTALL => [
-                'route' => self::CMD_INSTALL
-                    . " {$deployConfig} {$userConfig} {$adminUser} {$salesConfig}"
-                    . ' [--' . Installer::CLEANUP_DB . ']'
-                    . ' [--' . Installer::USE_SAMPLE_DATA . '=]',
-                'usage' => "{$deployConfig} {$userConfig} {$adminUser} {$salesConfig}"
-                    . ' [--' . Installer::CLEANUP_DB . ']'
-                    . ' [--' . Installer::USE_SAMPLE_DATA . '=]',
-                'usage_short' => self::CMD_INSTALL . ' <options>',
-                'usage_desc' => 'Install Magento application',
-            ],
-            self::CMD_UPDATE => [
-                'route' => self::CMD_UPDATE,
-                'usage' => '',
-                'usage_short' => self::CMD_UPDATE,
-                'usage_desc' => 'Update database schema and data',
-            ],
-            self::CMD_DB_STATUS => [
-                'route' => self::CMD_DB_STATUS,
-                'usage' => '',
-                'usage_short' => self::CMD_DB_STATUS,
-                'usage_desc' => 'Check if update of DB schema or data is required',
-            ],
-            self::CMD_UNINSTALL => [
-                'route' => self::CMD_UNINSTALL,
-                'usage' => '',
-                'usage_short' => self::CMD_UNINSTALL,
-                'usage_desc' => 'Uninstall Magento application',
-            ],
-            self::CMD_INSTALL_SCHEMA => [
-                'route' => self::CMD_INSTALL_SCHEMA,
-                'usage' => '',
-                'usage_short' => self::CMD_INSTALL_SCHEMA,
-                'usage_desc' => 'Install DB schema',
-            ],
-            self::CMD_INSTALL_DATA => [
-                'route' => self::CMD_INSTALL_DATA,
-                'usage' => '',
-                'usage_short' => self::CMD_INSTALL_DATA,
-                'usage_desc' => 'Install data fixtures',
-            ],
-            self::CMD_INSTALL_USER_CONFIG => [
-                'route' => self::CMD_INSTALL_USER_CONFIG . ' ' . $userConfig,
-                'usage' => $userConfig,
-                'usage_short' => self::CMD_INSTALL_USER_CONFIG . ' <options>',
-                'usage_desc' => 'Install user configuration',
-            ],
-            self::CMD_INSTALL_ADMIN_USER => [
-                'route' => self::CMD_INSTALL_ADMIN_USER . ' ' . $adminUser,
-                'usage' => $adminUser,
-                'usage_short' => self::CMD_INSTALL_ADMIN_USER . ' <options>',
-                'usage_desc' => 'Install admin user account',
-            ],
-            self::CMD_MAINTENANCE => [
-                'route' => self::CMD_MAINTENANCE . ' [--set=] [--addresses=]',
-                'usage' => '[--set=1|0] [--addresses=127.0.0.1,...|none]',
-                'usage_short' => self::CMD_MAINTENANCE,
-                'usage_desc' => 'Set maintenance mode, optionally for specified addresses',
-            ],
-            self::CMD_MODULE_ENABLE => [
-                'route' => self::CMD_MODULE_ENABLE . ' --modules= [--force]',
-                'usage' => '--modules=Module_Foo,Module_Bar [--force]',
-                'usage_short' => self::CMD_MODULE_ENABLE,
-                'usage_desc' => 'Enable specified modules'
-            ],
-            self::CMD_MODULE_DISABLE => [
-                'route' => self::CMD_MODULE_DISABLE . ' --modules= [--force]',
-                'usage' => '--modules=Module_Foo,Module_Bar [--force]',
-                'usage_short' => self::CMD_MODULE_DISABLE,
-                'usage_desc' => 'Disable specified modules'
-            ],
-            self::CMD_HELP => [
-                'route' => self::CMD_HELP . ' [' . implode('|', self::$helpOptions) . ']:type',
-                'usage' => '<' . implode('|', self::$helpOptions) . '>',
-                'usage_short' => self::CMD_HELP . ' <topic>',
-                'usage_desc' => 'Help about particular command or topic:',
-            ],
-        ];
-    }
-
-    /**
-     * Constructor
-     *
-     * @param ConsoleLogger $consoleLogger
-     * @param Lists $options
-     * @param InstallerFactory $installerFactory
-     * @param MaintenanceMode $maintenanceMode
-     * @param ObjectManagerProvider $objectManagerProvider
-     */
-    public function __construct(
-        ConsoleLogger $consoleLogger,
-        Lists $options,
-        InstallerFactory $installerFactory,
-        MaintenanceMode $maintenanceMode,
-        ObjectManagerProvider $objectManagerProvider
-    ) {
-        $this->log = $consoleLogger;
-        $this->options = $options;
-        $this->installer = $installerFactory->create($consoleLogger);
-        $this->maintenanceMode = $maintenanceMode;
-        $this->objectManagerProvider = $objectManagerProvider;
-        // By default we use our customized error handler, but for CLI we want to display all errors
-        restore_error_handler();
-    }
-
-    /**
-     * Adding Check for Allowing only console application to come through
-     *
-     * {@inheritdoc}
-     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
-     */
-    public function setEventManager(EventManagerInterface $events)
-    {
-        parent::setEventManager($events);
-        $controller = $this;
-        $events->attach('dispatch', function ($action) use ($controller) {
-            /** @var $action \Zend\Mvc\Controller\AbstractActionController */
-            // Make sure that we are running in a console and the user has not tricked our
-            // application into running this action from a public web server.
-            if (!$action->getRequest() instanceof ConsoleRequest) {
-                throw new \RuntimeException('You can only use this action from a console!');
-            }
-        }, 100); // execute before executing action logic
-        return $this;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function onDispatch(\Zend\Mvc\MvcEvent $e)
-    {
-        try {
-            return parent::onDispatch($e);
-        } catch (\Magento\Setup\Exception $exception) {
-            $this->log->log($exception->getMessage());
-            return $this->getResponse();
-        }
-    }
-
-    /**
-     * Controller for Install Command
-     *
-     * @return void
-     */
-    public function installAction()
-    {
-        /** @var \Zend\Console\Request $request */
-        $request = $this->getRequest();
-        $this->installer->install($request->getParams());
-    }
-
-    /**
-     * Installs and updates database schema
-     *
-     * @return void
-     */
-    public function installSchemaAction()
-    {
-        $this->installer->installSchema();
-    }
-
-    /**
-     * Installs and updates data fixtures
-     *
-     * @return void
-     */
-    public function installDataAction()
-    {
-        $this->installer->installDataFixtures();
-    }
-
-    /**
-     * Updates database schema and data
-     *
-     * @return void
-     */
-    public function updateAction()
-    {
-        $this->installer->updateModulesSequence();
-        $this->installer->installSchema();
-        $this->installer->installDataFixtures();
-    }
-
-    /**
-     * Checks if DB schema or data upgrade is required
-     *
-     * @return void
-     */
-    public function dbStatusAction()
-    {
-        /** @var DbVersionInfo $dbVersionInfo */
-        $dbVersionInfo = $this->objectManagerProvider->get()
-            ->get('Magento\Framework\Module\DbVersionInfo');
-        $outdated = $dbVersionInfo->getDbVersionErrors();
-        if (!empty($outdated)) {
-            $this->log->log("The module code base doesn't match the DB schema and data.");
-            $versionParser = new VersionParser();
-            $codebaseUpdateNeeded = false;
-            foreach ($outdated as $row) {
-                if (!$codebaseUpdateNeeded && $row[DbVersionInfo::KEY_CURRENT] !== 'none') {
-                    // check if module code base update is needed
-                    $currentVersion = $versionParser->parseConstraints($row[DbVersionInfo::KEY_CURRENT]);
-                    $requiredVersion = $versionParser->parseConstraints('>' . $row[DbVersionInfo::KEY_REQUIRED]);
-                    if ($requiredVersion->matches($currentVersion)) {
-                        $codebaseUpdateNeeded = true;
-                    };
-                }
-                $this->log->log(sprintf(
-                    "%20s %10s: %11s  ->  %-11s",
-                    $row[DbVersionInfo::KEY_MODULE],
-                    $row[DbVersionInfo::KEY_TYPE],
-                    $row[DbVersionInfo::KEY_CURRENT],
-                    $row[DbVersionInfo::KEY_REQUIRED]
-                ));
-            }
-            if ($codebaseUpdateNeeded) {
-                $this->log->log(
-                    'Some modules use code versions newer or older than the database. ' .
-                    'First update the module code, then run the "Update" command.'
-                );
-            } else {
-                $this->log->log('Run the "Update" command to update your DB schema and data');
-            }
-        } else {
-            $this->log->log('All modules are up to date');
-        }
-    }
-
-    /**
-     * Installs user configuration
-     *
-     * @return void
-     */
-    public function installUserConfigAction()
-    {
-        /** @var \Zend\Console\Request $request */
-        $request = $this->getRequest();
-        $this->installer->installUserConfig($request->getParams());
-    }
-
-    /**
-     * Installs admin user
-     *
-     * @return void
-     */
-    public function installAdminUserAction()
-    {
-        /** @var \Zend\Console\Request $request */
-        $request = $this->getRequest();
-        $this->installer->installAdminUser($request->getParams());
-    }
-
-    /**
-     * Controller for Uninstall Command
-     *
-     * @return void
-     */
-    public function uninstallAction()
-    {
-        $this->installer->uninstall();
-    }
-
-    /**
-     * Action for "maintenance" command
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     *
-     */
-    public function maintenanceAction()
-    {
-        /** @var \Zend\Console\Request $request */
-        $request = $this->getRequest();
-        $set = $request->getParam('set');
-        $addresses = $request->getParam('addresses');
-
-        if (null !== $set) {
-            if (1 == $set) {
-                $this->log->log('Enabling maintenance mode...');
-                $this->maintenanceMode->set(true);
-            } else {
-                $this->log->log('Disabling maintenance mode...');
-                $this->maintenanceMode->set(false);
-            }
-        }
-        if (null !== $addresses) {
-            $addresses = ('none' == $addresses) ? '' : $addresses;
-            $this->maintenanceMode->setAddresses($addresses);
-        }
-
-        $this->log->log('Status: maintenance mode is ' . ($this->maintenanceMode->isOn() ? 'active' : 'not active'));
-        $addressInfo = $this->maintenanceMode->getAddressInfo();
-        if (!empty($addressInfo)) {
-            $addresses = implode(', ', $addressInfo);
-            $this->log->log('List of exempt IP-addresses: ' . ($addresses ? $addresses : 'none'));
-        }
-    }
-
-    /**
-     * Action for enabling or disabling modules
-     *
-     * @return void
-     * @throws \Magento\Setup\Exception
-     */
-    public function moduleAction()
-    {
-        /** @var \Zend\Console\Request $request */
-        $request = $this->getRequest();
-        $isEnable = $request->getParam(0) == self::CMD_MODULE_ENABLE;
-        $modules = explode(',', $request->getParam('modules'));
-        /** @var \Magento\Framework\Module\Status $status */
-        $status = $this->objectManagerProvider->get()->create('Magento\Framework\Module\Status');
-
-        $modulesToChange = $status->getModulesToChange($isEnable, $modules);
-        $message = '';
-        if (!empty($modulesToChange)) {
-            if (!$request->getParam('force')) {
-                $constraints = $status->checkConstraints($isEnable, $modulesToChange);
-                if ($constraints) {
-                    $message .= "Unable to change status of modules because of the following constraints:\n"
-                        . implode("\n", $constraints);
-                    throw new \Magento\Setup\Exception($message);
-                }
-            } else {
-                $message .= 'Alert: Your store may not operate properly because of '
-                    . "dependencies and conflicts of this module(s).\n";
-            }
-            $status->setIsEnabled($isEnable, $modulesToChange);
-            $updateAfterEnableMessage = '';
-            if ($isEnable) {
-                $message .= 'The following modules have been enabled:';
-                $updateAfterEnableMessage = "\nTo make sure that the enabled modules are properly registered,"
-                    . " run 'update' command.";
-            } else {
-                $message .= 'The following modules have been disabled:';
-            }
-            $message .= ' ' . implode(', ', $modulesToChange) . $updateAfterEnableMessage;
-        } else {
-            $message .= 'There have been no changes to any modules.';
-        }
-        $this->log->log($message);
-    }
-
-    /**
-     * Shows necessary information for installing Magento
-     *
-     * @return string
-     * @throws \InvalidArgumentException
-     */
-    public function helpAction()
-    {
-        $type = $this->getRequest()->getParam('type');
-        if ($type === false) {
-            $usageInfo = $this->formatConsoleFullUsageInfo(
-                array_merge(self::getConsoleUsage(), InitParamListener::getConsoleUsage())
-            );
-            return $usageInfo;
-        }
-        switch($type) {
-            case UserConfig::KEY_LANGUAGE:
-                return $this->arrayToString($this->options->getLocaleList());
-            case UserConfig::KEY_CURRENCY:
-                return $this->arrayToString($this->options->getCurrencyList());
-            case UserConfig::KEY_TIMEZONE:
-                return $this->arrayToString($this->options->getTimezoneList());
-            case self::HELP_LIST_OF_MODULES:
-                return $this->getModuleListMsg();
-            default:
-                $usages = self::getCommandUsage();
-                if (isset($usages[$type])) {
-                    if ($usages[$type]) {
-                        $formatted = $this->formatCliUsage($usages[$type]);
-                        return "\nAvailable parameters:\n{$formatted}\n";
-                    }
-                    return "\nThis command has no parameters.\n";
-                }
-                throw new \InvalidArgumentException("Unknown type: {$type}");
-        }
-    }
-
-    /**
-     * Formats full usage info for console when user inputs 'help' command with no type
-     *
-     * @param array $usageInfo
-     * @return string
-     */
-    private function formatConsoleFullUsageInfo($usageInfo)
-    {
-        $result = "\n==-------------------==\n"
-            . "   Magento Setup CLI   \n"
-            . "==-------------------==\n";
-        $mask = "%-50s %-30s\n";
-        $script = 'index.php';
-        foreach ($usageInfo as $key => $value) {
-            if ($key === 0) {
-                $result .= sprintf($mask, "\n$value", '');
-            } elseif (is_numeric($key)) {
-                if (is_array($value)) {
-                    $result .= sprintf($mask, "  " . $value[0], $value[1]);
-                } else {
-                    $result .= sprintf($mask, '', $value);
-                }
-            } else {
-                $result .= sprintf($mask, "  $script " . $key, $value);
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Formats output of "usage" into more readable format by grouping required/optional parameters and wordwrapping
-     *
-     * @param string $text
-     * @return string
-     */
-    private function formatCliUsage($text)
-    {
-        $result = ['required' => [], 'optional' => []];
-        foreach (explode(' ', $text) as $value) {
-            if (empty($value)) {
-                continue;
-            }
-            if (strpos($value, '[') === 0) {
-                $group = 'optional';
-            } else {
-                $group = 'required';
-            }
-            $result[$group][] = $value;
-        }
-
-        return wordwrap(implode(' ', $result['required']) . "\n" . implode(' ', $result['optional']), 120);
-    }
-
-    /**
-     * Convert an array to string
-     *
-     * @param array $input
-     * @return string
-     */
-    private function arrayToString($input)
-    {
-        $result = '';
-        foreach ($input as $key => $value) {
-            $result .= "$key => $value\n";
-        }
-        return $result;
-    }
-
-    /**
-     * Get formatted message containing list of enabled and disabled modules
-     *
-     * @return string
-     */
-    private function getModuleListMsg()
-    {
-        $moduleList = $this->objectManagerProvider->get()->create('Magento\Framework\Module\ModuleList');
-        $result = "\nList of enabled modules:\n";
-        $enabledModuleList = $moduleList->getNames();
-        foreach ($enabledModuleList as $moduleName) {
-            $result .= "$moduleName\n";
-        }
-        if (count($enabledModuleList) === 0) {
-            $result .= "None\n";
-        }
-
-        $fullModuleList = $this->objectManagerProvider->get()->create('Magento\Framework\Module\FullModuleList');
-        $result .= "\nList of disabled modules:\n";
-        $disabledModuleList = array_diff($fullModuleList->getNames(), $enabledModuleList);
-        foreach ($disabledModuleList as $moduleName) {
-            $result .= "$moduleName\n";
-        }
-        if (count($disabledModuleList) === 0) {
-            $result .= "None\n";
-        }
-
-        return $result;
-    }
-}
diff --git a/setup/src/Magento/Setup/Controller/Install.php b/setup/src/Magento/Setup/Controller/Install.php
index 0618df92d08c81e9974c73079cf7ab6a66e8d078..87ca5ba26940acc55ddbe6b159aba0f0f01afe37 100644
--- a/setup/src/Magento/Setup/Controller/Install.php
+++ b/setup/src/Magento/Setup/Controller/Install.php
@@ -12,12 +12,13 @@ use Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
 use Magento\Setup\Model\Installer;
 use Magento\Setup\Model\Installer\ProgressFactory;
 use Magento\Setup\Model\InstallerFactory;
-use Magento\Setup\Model\UserConfigurationDataMapper as UserConfig;
+use Magento\Setup\Model\StoreConfigurationDataMapper as UserConfig;
 use Magento\Setup\Model\WebLogger;
 use Zend\Json\Json;
 use Zend\Mvc\Controller\AbstractActionController;
 use Zend\View\Model\JsonModel;
 use Zend\View\Model\ViewModel;
+use Magento\Setup\Console\Command\InstallCommand;
 
 /**
  * Install controller
@@ -131,7 +132,7 @@ class Install extends AbstractActionController
         $result[SetupConfigOptionsList::INPUT_KEY_DB_HOST] = isset($source['db']['host']) ? $source['db']['host'] : '';
         $result[SetupConfigOptionsList::INPUT_KEY_DB_NAME] = isset($source['db']['name']) ? $source['db']['name'] : '';
         $result[SetupConfigOptionsList::INPUT_KEY_DB_USER] = isset($source['db']['user']) ? $source['db']['user'] :'';
-        $result[SetupConfigOptionsList::INPUT_KEY_DB_PASS] =
+        $result[SetupConfigOptionsList::INPUT_KEY_DB_PASSWORD] =
             isset($source['db']['password']) ? $source['db']['password'] : '';
         $result[SetupConfigOptionsList::INPUT_KEY_DB_PREFIX] =
             isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : '';
@@ -175,7 +176,7 @@ class Install extends AbstractActionController
             ? $source['store']['timezone'] : '';
         $result[UserConfig::KEY_CURRENCY] = isset($source['store']['currency'])
             ? $source['store']['currency'] : '';
-        $result[Installer::USE_SAMPLE_DATA] = isset($source['store']['useSampleData'])
+        $result[InstallCommand::INPUT_KEY_USE_SAMPLE_DATA] = isset($source['store']['useSampleData'])
             ? $source['store']['useSampleData'] : '';
         return $result;
     }
@@ -189,11 +190,11 @@ class Install extends AbstractActionController
     {
         $source = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY);
         $result = [];
-        $result[AdminAccount::KEY_USERNAME] = isset($source['admin']['username']) ? $source['admin']['username'] : '';
+        $result[AdminAccount::KEY_USER] = isset($source['admin']['username']) ? $source['admin']['username'] : '';
         $result[AdminAccount::KEY_PASSWORD] = isset($source['admin']['password']) ? $source['admin']['password'] : '';
         $result[AdminAccount::KEY_EMAIL] = isset($source['admin']['email']) ? $source['admin']['email'] : '';
-        $result[AdminAccount::KEY_FIRST_NAME] = $result[AdminAccount::KEY_USERNAME];
-        $result[AdminAccount::KEY_LAST_NAME] = $result[AdminAccount::KEY_USERNAME];
+        $result[AdminAccount::KEY_FIRST_NAME] = $result[AdminAccount::KEY_USER];
+        $result[AdminAccount::KEY_LAST_NAME] = $result[AdminAccount::KEY_USER];
         return $result;
     }
 }
diff --git a/setup/src/Magento/Setup/Model/AdminAccount.php b/setup/src/Magento/Setup/Model/AdminAccount.php
index 2bd64aaecd675d2315be375e6a8761ab8d733b16..7e52b2b604e10f76f660e28d50f26cf59f3d2c6e 100644
--- a/setup/src/Magento/Setup/Model/AdminAccount.php
+++ b/setup/src/Magento/Setup/Model/AdminAccount.php
@@ -17,7 +17,7 @@ class AdminAccount
     /**#@+
      * Data keys
      */
-    const KEY_USERNAME = 'admin_username';
+    const KEY_USER = 'admin_user';
     const KEY_PASSWORD = 'admin_password';
     const KEY_EMAIL = 'admin_email';
     const KEY_FIRST_NAME = 'admin_firstname';
@@ -102,7 +102,7 @@ class AdminAccount
         $result = $this->setup->getConnection()->fetchRow(
             'SELECT user_id, username, email FROM ' . $this->setup->getTable('admin_user') . ' ' .
             'WHERE username = :username OR email = :email',
-            ['username' => $this->data[self::KEY_USERNAME], 'email' => $this->data[self::KEY_EMAIL]]
+            ['username' => $this->data[self::KEY_USER], 'email' => $this->data[self::KEY_EMAIL]]
         );
 
         if (!empty($result)) {
@@ -113,11 +113,11 @@ class AdminAccount
             $this->setup->getConnection()->update(
                 $this->setup->getTable('admin_user'),
                 $adminData,
-                $this->setup->getConnection()->quoteInto('username = ?', $this->data[self::KEY_USERNAME])
+                $this->setup->getConnection()->quoteInto('username = ?', $this->data[self::KEY_USER])
             );
         } else {
             // User does not exist, create it
-            $adminData['username'] = $this->data[self::KEY_USERNAME];
+            $adminData['username'] = $this->data[self::KEY_USER];
             $adminData['email'] = $this->data[self::KEY_EMAIL];
             $adminData['extra'] = serialize(null);
             $this->setup->getConnection()->insert(
@@ -140,18 +140,18 @@ class AdminAccount
     private function validateUserMatches($username, $email)
     {
         if ((strcasecmp($email, $this->data[self::KEY_EMAIL]) == 0) &&
-            (strcasecmp($username, $this->data[self::KEY_USERNAME]) != 0)) {
+            (strcasecmp($username, $this->data[self::KEY_USER]) != 0)) {
             // email matched but username did not
             throw new \Exception(
-                'An existing user has the given email but different username. ' . self::KEY_USERNAME .
+                'An existing user has the given email but different username. ' . self::KEY_USER .
                 ' and ' . self::KEY_EMAIL . ' both need to match an existing user or both be new.'
             );
         }
-        if ((strcasecmp($username, $this->data[self::KEY_USERNAME]) == 0) &&
+        if ((strcasecmp($username, $this->data[self::KEY_USER]) == 0) &&
             (strcasecmp($email, $this->data[self::KEY_EMAIL]) != 0)) {
             // username matched but email did not
             throw new \Exception(
-                'An existing user has the given username but different email. ' . self::KEY_USERNAME .
+                'An existing user has the given username but different email. ' . self::KEY_USER .
                 ' and ' . self::KEY_EMAIL . ' both need to match an existing user or both be new.'
             );
         }
@@ -180,7 +180,7 @@ class AdminAccount
                 'role_type'  => User::ROLE_TYPE,
                 'user_id'    => $adminId,
                 'user_type'  => UserContextInterface::USER_TYPE_ADMIN,
-                'role_name'  => $this->data[self::KEY_USERNAME],
+                'role_name'  => $this->data[self::KEY_USER],
             ];
             $this->setup->getConnection()->insert($this->setup->getTable('authorization_role'), $adminRoleData);
         }
diff --git a/setup/src/Magento/Setup/Model/ConsoleLogger.php b/setup/src/Magento/Setup/Model/ConsoleLogger.php
index e0c0aa147272977e68f05fd731614284be45b5b5..3bcd21aabe083ce1066554ca661e2b4e270e2916 100644
--- a/setup/src/Magento/Setup/Model/ConsoleLogger.php
+++ b/setup/src/Magento/Setup/Model/ConsoleLogger.php
@@ -6,8 +6,8 @@
 
 namespace Magento\Setup\Model;
 
-use Zend\Console\ColorInterface;
-use Zend\Console\Console;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 
 /**
  * Console Logger
@@ -26,16 +26,21 @@ class ConsoleLogger implements LoggerInterface
     /**
      * Console
      *
-     * @var \Zend\Console\Adapter\AdapterInterface
+     * @var OutputInterface
      */
     protected $console;
 
     /**
      * Constructor
+     *
+     * @param OutputInterface $output
      */
-    public function __construct()
+    public function __construct(OutputInterface $output)
     {
-        $this->console = Console::getInstance();
+        $this->console = $output;
+        $outputFormatter = $this->console->getFormatter();
+        $outputFormatter->setStyle('detail', new OutputFormatterStyle('blue'));
+        $outputFormatter->setStyle('metadata', new OutputFormatterStyle('cyan'));
     }
 
     /**
@@ -44,7 +49,7 @@ class ConsoleLogger implements LoggerInterface
     public function logSuccess($message)
     {
         $this->terminateLine();
-        $this->console->writeLine("[SUCCESS]" . ($message ? ": $message" : ''), ColorInterface::LIGHT_GREEN);
+        $this->console->writeln("<info>[SUCCESS]" . ($message ? ": $message" : '') . '</info>');
     }
 
     /**
@@ -53,7 +58,7 @@ class ConsoleLogger implements LoggerInterface
     public function logError(\Exception $e)
     {
         $this->terminateLine();
-        $this->console->writeLine("[ERROR]: " . $e, ColorInterface::LIGHT_RED);
+        $this->console->writeln("<error>[ERROR]: " . $e . '</error>');
     }
 
     /**
@@ -62,7 +67,7 @@ class ConsoleLogger implements LoggerInterface
     public function log($message)
     {
         $this->terminateLine();
-        $this->console->writeLine($message, ColorInterface::LIGHT_BLUE);
+        $this->console->writeln('<detail>' . $message . '</detail>');
     }
 
     /**
@@ -71,7 +76,7 @@ class ConsoleLogger implements LoggerInterface
     public function logInline($message)
     {
         $this->isInline = true;
-        $this->console->write($message, ColorInterface::LIGHT_BLUE);
+        $this->console->write('<detail>' . $message . '</detail>');
     }
 
     /**
@@ -80,7 +85,7 @@ class ConsoleLogger implements LoggerInterface
     public function logMeta($message)
     {
         $this->terminateLine();
-        $this->console->writeLine($message, ColorInterface::GRAY);
+        $this->console->writeln('<metadata>' . $message . '</metadata>');
     }
 
     /**
@@ -92,7 +97,7 @@ class ConsoleLogger implements LoggerInterface
     {
         if ($this->isInline) {
             $this->isInline = false;
-            $this->console->writeLine('');
+            $this->console->writeln('');
         }
     }
 }
diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php
index 451c0c06800a1fe01d04d079bc34b8e503ddbe15..5db3a546a66113ea49ff556c9f346281ec8afc44 100644
--- a/setup/src/Magento/Setup/Model/Installer.php
+++ b/setup/src/Magento/Setup/Model/Installer.php
@@ -29,6 +29,8 @@ use Magento\Store\Model\Store;
 use Magento\Setup\Module\ConnectionFactory;
 use Magento\Setup\Module\Setup;
 use Magento\Framework\Config\File\ConfigFilePool;
+use Magento\Framework\App\State\CleanupFiles;
+use Magento\Setup\Console\Command\InstallCommand;
 
 /**
  * Class Installer contains the logic to install Magento application.
@@ -39,11 +41,6 @@ use Magento\Framework\Config\File\ConfigFilePool;
  */
 class Installer
 {
-    /**
-     * Parameter indicating command whether to cleanup database in the install routine
-     */
-    const CLEANUP_DB = 'cleanup_database';
-
     /**#@+
      * Parameters for enabling/disabling modules
      */
@@ -51,16 +48,6 @@ class Installer
     const DISABLE_MODULES = 'disable_modules';
     /**#@- */
 
-    /**
-     * Parameter indicating command whether to install Sample Data
-     */
-    const USE_SAMPLE_DATA = 'use_sample_data';
-
-    /**
-     * Parameter to specify an order_increment_prefix
-     */
-    const SALES_ORDER_INCREMENT_PREFIX = 'sales_order_increment_prefix';
-
     /**#@+
      * Formatting for progress log
      */
@@ -193,6 +180,11 @@ class Installer
      */
     private $setupConfigModel;
 
+    /**
+     * @var CleanupFiles
+     */
+    private $cleanupFiles;
+
     /**
      * Constructor
      *
@@ -211,7 +203,8 @@ class Installer
      * @param ObjectManagerProvider $objectManagerProvider
      * @param Context $context
      * @param SetupConfigModel $setupConfigModel
-     * 
+     * @param CleanupFiles $cleanupFiles
+     *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -229,7 +222,8 @@ class Installer
         SampleData $sampleData,
         ObjectManagerProvider $objectManagerProvider,
         Context $context,
-        SetupConfigModel $setupConfigModel
+        SetupConfigModel $setupConfigModel,
+        CleanupFiles $cleanupFiles
     ) {
         $this->filePermissions = $filePermissions;
         $this->deploymentConfigWriter = $deploymentConfigWriter;
@@ -247,6 +241,7 @@ class Installer
         $this->objectManagerProvider = $objectManagerProvider;
         $this->context = $context;
         $this->setupConfigModel = $setupConfigModel;
+        $this->cleanupFiles = $cleanupFiles;
     }
 
     /**
@@ -261,22 +256,22 @@ class Installer
         $script[] = ['File permissions check...', 'checkInstallationFilePermissions', []];
         $script[] = ['Enabling Maintenance Mode...', 'setMaintenanceMode', [1]];
         $script[] = ['Installing deployment configuration...', 'installDeploymentConfig', [$request]];
-        if (!empty($request[self::CLEANUP_DB])) {
+        if (!empty($request[InstallCommand::INPUT_KEY_CLEANUP_DB])) {
             $script[] = ['Cleaning up database...', 'cleanupDb', []];
         }
         $script[] = ['Installing database schema:', 'installSchema', []];
         $script[] = ['Installing user configuration...', 'installUserConfig', [$request]];
         $script[] = ['Installing data...', 'installDataFixtures', []];
-        if (!empty($request[self::SALES_ORDER_INCREMENT_PREFIX])) {
+        if (!empty($request[InstallCommand::INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX])) {
             $script[] = [
                 'Creating sales order increment prefix...',
                 'installOrderIncrementPrefix',
-                [$request[self::SALES_ORDER_INCREMENT_PREFIX]],
+                [$request[InstallCommand::INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX]],
             ];
         }
         $script[] = ['Installing admin user...', 'installAdminUser', [$request]];
         $script[] = ['Enabling caches:', 'enableCaches', []];
-        if (!empty($request[Installer::USE_SAMPLE_DATA]) && $this->sampleData->isDeployed()) {
+        if (!empty($request[InstallCommand::INPUT_KEY_USE_SAMPLE_DATA]) && $this->sampleData->isDeployed()) {
             $script[] = ['Installing sample data:', 'installSampleData', [$request]];
         }
         $script[] = ['Disabling Maintenance Mode:', 'setMaintenanceMode', [0]];
@@ -420,12 +415,7 @@ class Installer
     {
         $this->checkInstallationFilePermissions();
         $userData = is_array($data) ? $data : $data->getArrayCopy();
-
-        // TODO: remove this when moving install command to symfony
-        $userData = $this->setDefaultValues($userData);
-
         $this->setupConfigModel->process($userData);
-
         if ($this->deploymentConfig->isAvailable()) {
             $deploymentConfigData = $this->deploymentConfig->get(ConfigOptionsList::CONFIG_PATH_CRYPT_KEY);
             if (isset($deploymentConfigData)) {
@@ -435,32 +425,6 @@ class Installer
         // reset object manager now that there is a deployment config
         $this->objectManagerProvider->reset();
     }
-    
-    /**
-     * Sets defaults if user input is missing
-     *
-     * @param array $userData
-     * @return array
-     */
-    private function setDefaultValues(array $userData)
-    {
-        if (!isset($userData[ConfigOptionsList::INPUT_KEY_SESSION_SAVE])) {
-            $userData[ConfigOptionsList::INPUT_KEY_SESSION_SAVE] = ConfigOptionsList::SESSION_SAVE_FILES;
-        }
-        if (!isset($userData[ConfigOptionsList::INPUT_KEY_DB_PASS])) {
-            $userData[ConfigOptionsList::INPUT_KEY_DB_PASS] = '';
-        }
-        if (!isset($userData[ConfigOptionsList::INPUT_KEY_DB_MODEL])) {
-            $userData[ConfigOptionsList::INPUT_KEY_DB_MODEL] = 'mysql4';
-        }
-        if (!isset($userData[ConfigOptionsList::INPUT_KEY_DB_INIT_STATEMENTS])) {
-            $userData[ConfigOptionsList::INPUT_KEY_DB_INIT_STATEMENTS] = 'SET NAMES utf8;';
-        }
-        if (!isset($userData[ConfigOptionsList::INPUT_KEY_DB_PREFIX])) {
-            $userData[ConfigOptionsList::INPUT_KEY_DB_PREFIX] = '';
-        }
-        return $userData;
-    }
 
     /**
      * Set up setup_module table to register modules' versions, skip this process if it already exists
@@ -822,7 +786,7 @@ class Installer
      */
     public function installUserConfig($data)
     {
-        $userConfig = new UserConfigurationDataMapper();
+        $userConfig = new StoreConfigurationDataMapper();
         $configData = $userConfig->getConfigData($data);
         if (count($configData) === 0) {
             return;
@@ -909,9 +873,14 @@ class Installer
     public function updateModulesSequence()
     {
         $this->assertDeploymentConfigExists();
+
+        $this->clearCache();
+
         $this->log->log('File system cleanup:');
-        $this->deleteDirContents(DirectoryList::GENERATION);
-        $this->deleteDirContents(DirectoryList::CACHE);
+        $messages = $this->cleanupFiles->clearCodeGeneratedClasses();
+        foreach ($messages as $message) {
+            $this->log->log($message);
+        }
         $this->log->log('Updating modules:');
         $this->createModulesConfig([]);
     }
@@ -926,14 +895,31 @@ class Installer
         $this->log->log('Starting Magento uninstallation:');
 
         $this->cleanupDb();
+        $this->clearCache();
+
         $this->log->log('File system cleanup:');
-        $this->deleteDirContents(DirectoryList::VAR_DIR);
-        $this->deleteDirContents(DirectoryList::STATIC_VIEW);
+        $messages = $this->cleanupFiles->clearAllFiles();
+        foreach ($messages as $message) {
+            $this->log->log($message);
+        }
+
         $this->deleteDeploymentConfig();
 
         $this->log->logSuccess('Magento uninstallation complete.');
     }
 
+    /**
+     * Clears cache
+     *
+     * @return void
+     */
+    private function clearCache()
+    {
+        $cache = $this->objectManagerProvider->get()->create('Magento\Framework\App\Cache');
+        $cache->clean();
+        $this->log->log('Cache cleared successfully');
+    }
+
     /**
      * Enables caches after installing application
      *
@@ -1065,33 +1051,6 @@ class Installer
         $this->log->log('No database connection defined - skipping database cleanup');
     }
 
-    /**
-     * Removes contents of a directory
-     *
-     * @param string $type
-     * @return void
-     */
-    private function deleteDirContents($type)
-    {
-        $dir = $this->filesystem->getDirectoryWrite($type);
-        $dirPath = $dir->getAbsolutePath();
-        if (!$dir->isExist()) {
-            $this->log->log("The directory '{$dirPath}' doesn't exist - skipping cleanup");
-            return;
-        }
-        foreach ($dir->read() as $path) {
-            if (preg_match('/^\./', $path)) {
-                continue;
-            }
-            $this->log->log("{$dirPath}{$path}");
-            try {
-                $dir->delete($path);
-            } catch (FileSystemException $e) {
-                $this->log->log($e->getMessage());
-            }
-        }
-    }
-
     /**
      * Removes deployment configuration
      *
@@ -1140,7 +1099,7 @@ class Installer
             $connectionConfig[ConfigOptionsList::KEY_NAME],
             $connectionConfig[ConfigOptionsList::KEY_HOST],
             $connectionConfig[ConfigOptionsList::KEY_USER],
-            $connectionConfig[ConfigOptionsList::KEY_PASS]
+            $connectionConfig[ConfigOptionsList::KEY_PASSWORD]
         );
         if (isset($connectionConfig[ConfigOptionsList::KEY_PREFIX])) {
             $this->checkDatabaseTablePrefix($connectionConfig[ConfigOptionsList::KEY_PREFIX]);
@@ -1157,7 +1116,7 @@ class Installer
      */
     private function installSampleData($request)
     {
-        $userName = isset($request[AdminAccount::KEY_USERNAME]) ? $request[AdminAccount::KEY_USERNAME] : '';
+        $userName = isset($request[AdminAccount::KEY_USER]) ? $request[AdminAccount::KEY_USER] : '';
         $this->sampleData->install($this->objectManagerProvider->get(), $this->log, $userName);
     }
 
diff --git a/setup/src/Magento/Setup/Model/InstallerFactory.php b/setup/src/Magento/Setup/Model/InstallerFactory.php
index 3f12a06c8ffd7b46cdcf62d183f0defdc2e62c55..ce6bb1c99434580b03b8e8385b3deb7dd148bc2e 100644
--- a/setup/src/Magento/Setup/Model/InstallerFactory.php
+++ b/setup/src/Magento/Setup/Model/InstallerFactory.php
@@ -9,6 +9,7 @@ namespace Magento\Setup\Model;
 use Zend\ServiceManager\ServiceLocatorInterface;
 use Magento\Setup\Module\ResourceFactory;
 use Magento\Framework\App\ErrorHandler;
+use Magento\Framework\App\State\CleanupFiles;
 
 class InstallerFactory
 {
@@ -66,7 +67,8 @@ class InstallerFactory
                 $this->serviceLocator->get('Magento\Framework\Model\Resource\Db\TransactionManager'),
                 $this->serviceLocator->get('Magento\Framework\Model\Resource\Db\ObjectRelationProcessor')
             ),
-            $this->serviceLocator->get('Magento\Setup\Model\ConfigModel')
+            $this->serviceLocator->get('Magento\Setup\Model\ConfigModel'),
+            $this->serviceLocator->get('Magento\Framework\App\State\CleanupFiles')
         );
     }
 
diff --git a/setup/src/Magento/Setup/Model/UserConfigurationDataMapper.php b/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
similarity index 70%
rename from setup/src/Magento/Setup/Model/UserConfigurationDataMapper.php
rename to setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
index e9985cb4d52cc4d420bd9f04f94b44f1566e7262..0fa3c235244568c8a4e7dbf2595c658f87f9dd68 100644
--- a/setup/src/Magento/Setup/Model/UserConfigurationDataMapper.php
+++ b/setup/src/Magento/Setup/Model/StoreConfigurationDataMapper.php
@@ -17,7 +17,7 @@ use Magento\Store\Model\Store;
  *
  * @package Magento\Setup\Model
  */
-class UserConfigurationDataMapper
+class StoreConfigurationDataMapper
 {
     /**#@+
      * Model data keys
@@ -43,6 +43,8 @@ class UserConfigurationDataMapper
         Store::XML_PATH_UNSECURE_BASE_URL => self::KEY_BASE_URL,
         Store::XML_PATH_SECURE_BASE_URL => self::KEY_BASE_URL_SECURE,
         Data::XML_PATH_DEFAULT_LOCALE => self::KEY_LANGUAGE,
+        Store::XML_PATH_SECURE_IN_FRONTEND  => self::KEY_IS_SECURE,
+        Store::XML_PATH_SECURE_IN_ADMINHTML => self::KEY_IS_SECURE_ADMIN,
         Data::XML_PATH_DEFAULT_TIMEZONE => self::KEY_TIMEZONE,
         Currency::XML_PATH_CURRENCY_BASE => self::KEY_CURRENCY,
         Currency::XML_PATH_CURRENCY_DEFAULT => self::KEY_CURRENCY,
@@ -59,20 +61,6 @@ class UserConfigurationDataMapper
     public function getConfigData($installParamData)
     {
         $configData = [];
-        if (!$this->isSecureUrlNeeded($installParamData) && isset($installParamData[self::KEY_BASE_URL_SECURE])) {
-            unset($installParamData[self::KEY_BASE_URL_SECURE]);
-        }
-
-        // Base URL is secure, add secure entries
-        if (isset($installParamData[self::KEY_BASE_URL_SECURE])) {
-            $this->pathDataMap = array_merge(
-                $this->pathDataMap,
-                [
-                    Store::XML_PATH_SECURE_IN_FRONTEND  => self::KEY_IS_SECURE,
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => self::KEY_IS_SECURE_ADMIN
-                ]
-            );
-        }
 
         foreach ($this->pathDataMap as $path => $key) {
             $configData = $this->addParamToConfigData($configData, $installParamData, $key, $path);
@@ -80,18 +68,6 @@ class UserConfigurationDataMapper
         return $configData;
     }
 
-    /**
-     * Determine if secure URL is needed (use_secure or use_secure_admin flag is set.)
-     *
-     * @param array $installParamData
-     * @return bool
-     */
-    private function isSecureUrlNeeded($installParamData)
-    {
-        return ((isset($installParamData[self::KEY_IS_SECURE]) && $installParamData[self::KEY_IS_SECURE])
-            || (isset($installParamData[self::KEY_IS_SECURE_ADMIN]) && $installParamData[self::KEY_IS_SECURE_ADMIN]));
-    }
-
     /**
      * Adds an install parameter value to the configData structure
      *
diff --git a/setup/src/Magento/Setup/Module.php b/setup/src/Magento/Setup/Module.php
index 10141ca8f7e6416d1589a676da4268501e9b1ba8..55dd70b8c7b68ef24bf3c840b3bcd43a729998a5 100644
--- a/setup/src/Magento/Setup/Module.php
+++ b/setup/src/Magento/Setup/Module.php
@@ -6,7 +6,6 @@
 
 namespace Magento\Setup;
 
-use Magento\Setup\Mvc\Bootstrap\InitParamListener;
 use Magento\Setup\Mvc\View\Http\InjectTemplateListener;
 use Zend\EventManager\EventInterface;
 use Zend\ModuleManager\Feature\BootstrapListenerInterface;
@@ -66,7 +65,6 @@ class Module implements
             include __DIR__ . '/../../../config/states.config.php',
             include __DIR__ . '/../../../config/languages.config.php'
         );
-        $result = InitParamListener::attachToConsoleRoutes($result);
         return $result;
     }
 }
diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
index 19e6317e96e43c24b996cc194c1c8addc238fe41..1d229e825f9c8f43c165e93bf62574ea9b34c0af 100644
--- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
+++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php
@@ -39,45 +39,6 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface
      */
     private $listeners = [];
 
-    /**
-     * Registers itself to every command in console routes
-     *
-     * @param array $config
-     * @return array
-     */
-    public static function attachToConsoleRoutes($config)
-    {
-        if (isset($config['console']['router']['routes'])) {
-            foreach ($config['console']['router']['routes'] as &$route) {
-                $route['options']['route'] .= ' [--' . self::BOOTSTRAP_PARAM . '=]';
-            }
-        }
-        return $config;
-    }
-
-    /**
-     * Adds itself to CLI usage instructions
-     *
-     * @return array
-     */
-    public static function getConsoleUsage()
-    {
-        $result = [''];
-        $result[] = [
-            '[--' . self::BOOTSTRAP_PARAM . sprintf('=%s]', escapeshellarg('<query>')),
-            'Add to any command to customize Magento initialization parameters',
-        ];
-        $mode = State::PARAM_MODE;
-        $dirs = AppBootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS;
-        $examples = [
-            "{$mode}=developer",
-            "{$dirs}[base][path]=/var/www/example.com",
-            "{$dirs}[cache][path]=/var/tmp/cache",
-        ];
-        $result[] = ['', sprintf('For example: %s', escapeshellarg(implode('&', $examples)))];
-        return $result;
-    }
-
     /**
      * {@inheritdoc}
      */
diff --git a/setup/src/Magento/Setup/Mvc/Console/RouteListener.php b/setup/src/Magento/Setup/Mvc/Console/RouteListener.php
deleted file mode 100644
index 5b4dcbfde5a8c935edd544627be8aeae85ee70a7..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Mvc/Console/RouteListener.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Mvc\Console;
-
-use Zend\View\Model\ConsoleModel;
-use Zend\Mvc\Router\RouteMatch;
-use Zend\Mvc\MvcEvent;
-use Zend\Console\ColorInterface;
-use Zend\EventManager\EventManagerInterface;
-
-/**
- * Custom route listener to validate user parameters
- */
-class RouteListener extends \Zend\Mvc\RouteListener
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function onRoute($e)
-    {
-        $request = $e->getRequest();
-        // propagates to default RouteListener if not CLI
-        if (!$request instanceof \Zend\Console\Request) {
-            return null;
-        }
-
-        $router = $e->getRouter();
-        $match = $router->match($request);
-
-        // CLI routing miss, checks for missing/extra parameters
-        if (!$match instanceof RouteMatch) {
-            $content = $request->getContent();
-            $config = $e->getApplication()->getServiceManager()->get('Config')['console']['router']['routes'];
-
-            $verboseValidator = new VerboseValidator();
-            $validationMessages = $verboseValidator->validate($content, $config);
-
-            if ('' !== $validationMessages) {
-                $this->displayMessages($e, $validationMessages);
-                // set error to stop propagation
-                $e->setError('default_error');
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Display messages on console
-     *
-     * @param MvcEvent $e
-     * @param string $validationMessages
-     * @return void
-     */
-    private function displayMessages(MvcEvent $e, $validationMessages)
-    {
-        /** @var \Zend\Console\Adapter\AdapterInterface $console */
-        $console = $e->getApplication()->getServiceManager()->get('console');
-        $validationMessages = $console->colorize($validationMessages, ColorInterface::RED);
-        $model = new ConsoleModel();
-        $model->setErrorLevel(1);
-        $model->setResult($validationMessages);
-        $e->setResult($model);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function attach(EventManagerInterface $events)
-    {
-        // set a higher priority than default route listener so it gets triggered first
-        $this->listeners[] = $events->attach(MvcEvent::EVENT_ROUTE, [$this, 'onRoute'], 10);
-    }
-}
diff --git a/setup/src/Magento/Setup/Mvc/Console/RouteMatcher.php b/setup/src/Magento/Setup/Mvc/Console/RouteMatcher.php
deleted file mode 100644
index 7e2fc9dfd558f98dc4331c5ac60a3e864657c2b7..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Mvc/Console/RouteMatcher.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Mvc\Console;
-
-/**
- * Extending ZF RouteMatcher for a public getter
- */
-class RouteMatcher extends \Zend\Console\RouteMatcher\DefaultRouteMatcher
-{
-    /**
-     * Public getter of parts, used for parameters validation
-     *
-     * @return array
-     */
-    public function getParts()
-    {
-        return $this->parts;
-    }
-}
diff --git a/setup/src/Magento/Setup/Mvc/Console/VerboseValidator.php b/setup/src/Magento/Setup/Mvc/Console/VerboseValidator.php
deleted file mode 100644
index 1da4628b2b3573380d6363c22e5ecc32183afae1..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Mvc/Console/VerboseValidator.php
+++ /dev/null
@@ -1,237 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Mvc\Console;
-
-use Magento\Setup\Controller\ConsoleController;
-
-/**
- * Validator for checking parameters in CLI
- */
-class VerboseValidator
-{
-    /**
-     * Checks parameters and returns validation messages
-     *
-     * @param array $data
-     * @param array $config
-     * @return string
-     */
-    public function validate(array $data, array $config)
-    {
-        $validationMessages = '';
-        $userAction = null;
-        if (!empty($data)) {
-            $userAction = $data[0];
-            array_shift($data);
-        }
-        if (isset($userAction) && isset($config[$userAction])) {
-            // parse the expected parameters of the action
-            $matcher = new RouteMatcher($config[$userAction]['options']['route']);
-            $parts = $matcher->getParts();
-            array_shift($parts);
-            $expectedParams = [];
-            foreach ($parts as $part) {
-                $expectedParams[$part['name']] = $part;
-            }
-            // parse user parameters
-            $userParams = $this->parseUserParams($data);
-            $validationMessages = $this->validateParameters($expectedParams, $userParams);
-
-            // add usage message
-            $usages = ConsoleController::getCommandUsage();
-            $validationMessages .= 'Usage:' . PHP_EOL . "{$userAction} ";
-            $validationMessages .= $usages[$userAction] . PHP_EOL . PHP_EOL;
-
-        } else {
-            if (!is_null($userAction)) {
-                $validationMessages .= PHP_EOL . "Unknown action name '{$userAction}'." . PHP_EOL . PHP_EOL;
-            } else {
-                $validationMessages .= PHP_EOL . "No action is given in the command." . PHP_EOL . PHP_EOL;
-            }
-            $validationMessages .= 'Available options: ' . PHP_EOL;
-            foreach (array_keys($config) as $action) {
-                $validationMessages .= $action . PHP_EOL;
-            }
-            $validationMessages .= PHP_EOL;
-        }
-
-        return $validationMessages;
-    }
-
-    /**
-     * Parse user input
-     *
-     * @param array $content
-     * @return array
-     */
-    private function parseUserParams(array $content)
-    {
-        $parameters = [];
-        foreach ($content as $param) {
-            $parsed = explode('=', $param, 2);
-            $value = isset($parsed[1]) ? $parsed[1] : '';
-            if (strpos($parsed[0], '--') !== false) {
-                $key = substr($parsed[0], 2, strlen($parsed[0]) - 2);
-            } else {
-                $key = $parsed[0];
-            }
-
-            $parameters[$key] = $value;
-        }
-        return $parameters;
-    }
-    /**
-     * Check for any missing parameters
-     *
-     * @param array $expectedParams
-     * @param array $actualParams
-     * @return array
-     */
-    public function checkMissingParameter($expectedParams, $actualParams)
-    {
-        $missingParams = array_diff(array_keys($expectedParams), array_keys($actualParams));
-        foreach ($missingParams as $key => $missingParam) {
-            /* disregard if optional parameter */
-            if (!$expectedParams[$missingParam]['required']) {
-                unset($missingParams[$key]);
-            }
-        }
-        // some parameters have alternative names, verify user input with theses alternative names
-        foreach ($missingParams as $key => $missingParam) {
-            foreach (array_keys($actualParams) as $actualParam) {
-                if (isset($expectedParams[$missingParam]['alternatives'])) {
-                    foreach ($expectedParams[$missingParam]['alternatives'] as $alternative) {
-                        if ($actualParam === $alternative) {
-                            unset($missingParams[$key]);
-                            break 2;
-                        }
-                    }
-                }
-            }
-        }
-        return $missingParams;
-    }
-
-    /**
-     * Check for any extra parameters
-     *
-     * @param array $expectedParams
-     * @param array $actualParams
-     * @return array
-     */
-    public function checkExtraParameter($expectedParams, $actualParams)
-    {
-        $extraParams = array_diff(array_keys($actualParams), array_keys($expectedParams));
-        // some parameters have alternative names, make sure $extraParams doesn't contain these alternatives names
-        foreach ($extraParams as $key => $extraParam) {
-            foreach ($expectedParams as $expectedParam) {
-                if (isset($expectedParam['alternatives'])) {
-                    foreach ($expectedParam['alternatives'] as $alternative) {
-                        if ($extraParam === $alternative) {
-                            unset($extraParams[$key]);
-                            break 2;
-                        }
-                    }
-                }
-            }
-        }
-        return $extraParams;
-    }
-
-    /**
-     * Checks for parameters that are missing values
-     *
-     * @param array $expectedParams
-     * @param array $actualParams
-     * @return array
-     */
-    public function checkMissingValue($expectedParams, $actualParams)
-    {
-        $missingValues = [];
-        foreach ($actualParams as $param => $value) {
-            if (isset($expectedParams[$param])) {
-                if ($value === '' && $expectedParams[$param]['hasValue']) {
-                    $missingValues[] = $param;
-                }
-            }
-        }
-        return $missingValues;
-    }
-
-    /**
-     * Checks for parameters that do not need values
-     *
-     * @param array $expectedParams
-     * @param array $actualParams
-     * @return array
-     */
-    public function checkExtraValue($expectedParams, $actualParams)
-    {
-        $extraValues = [];
-        foreach ($actualParams as $param => $value) {
-            if (isset($expectedParams[$param])) {
-                if ($value !== '' && !$expectedParams[$param]['hasValue']) {
-                    $extraValues[] = $param;
-                }
-            }
-        }
-        return $extraValues;
-    }
-
-    /**
-     * Validates the parameters.
-     *
-     * @param array $expectedParams
-     * @param array $userParams
-     * @return string
-     *
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     */
-    private function validateParameters($expectedParams, $userParams)
-    {
-        $missingParams = $this->checkMissingParameter($expectedParams, $userParams);
-        $extraParams = $this->checkExtraParameter($expectedParams, $userParams);
-        $missingValues = $this->checkMissingValue($expectedParams, $userParams);
-        $extraValues = $this->checkExtraValue($expectedParams, $userParams);
-        $validationMessages = PHP_EOL;
-        if (!empty($missingParams)) {
-            $validationMessages .= 'Missing required parameters:' . PHP_EOL;
-            foreach ($missingParams as $missingParam) {
-                $validationMessages .= $missingParam . PHP_EOL;
-            }
-            $validationMessages .= PHP_EOL;
-        }
-        if (!empty($extraParams)) {
-            $validationMessages .= 'Unidentified parameters:' . PHP_EOL;
-            foreach ($extraParams as $extraParam) {
-                $validationMessages .= $extraParam . PHP_EOL;
-            }
-            $validationMessages .= PHP_EOL;
-        }
-        if (!empty($missingValues)) {
-            $validationMessages .= 'Parameters missing value:' . PHP_EOL;
-            foreach ($missingValues as $missingValue) {
-                $validationMessages .= $missingValue . PHP_EOL;
-            }
-            $validationMessages .= PHP_EOL;
-        }
-        if (!empty($extraValues)) {
-            $validationMessages .= 'Parameters that don\'t need value:' . PHP_EOL;
-            foreach ($extraValues as $extraValue) {
-                $validationMessages .= $extraValue . PHP_EOL;
-            }
-            $validationMessages .= PHP_EOL;
-        }
-        if (empty($missingParams) && empty($extraParams) && empty($missingValues) && empty($extraValue)) {
-            $validationMessages .= 'Please make sure parameters are in correct format and are not repeated.';
-            $validationMessages .= PHP_EOL . PHP_EOL;
-            return $validationMessages;
-        }
-        return $validationMessages;
-    }
-}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e8ad803fd37af25053bb648cfe69412a42348d6
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/AdminUserCreateCommandTest.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Model\AdminAccount;
+use Magento\Setup\Console\Command\AdminUserCreateCommand;
+use Magento\Setup\Mvc\Bootstrap\InitParamListener;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class AdminUserCreateCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\InstallerFactory
+     */
+    private $installerFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|AdminUserCreateCommand
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->installerFactoryMock = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $this->command = new AdminUserCreateCommand($this->installerFactoryMock);
+    }
+
+    public function testExecute()
+    {
+        $options = [
+            '--' . AdminAccount::KEY_USER => 'user',
+            '--' . AdminAccount::KEY_PASSWORD => '123123q',
+            '--' . AdminAccount::KEY_EMAIL => 'test@test.com',
+            '--' . AdminAccount::KEY_FIRST_NAME => 'John',
+            '--' . AdminAccount::KEY_LAST_NAME => 'Doe',
+        ];
+        $data = [
+            AdminAccount::KEY_USER => 'user',
+            AdminAccount::KEY_PASSWORD => '123123q',
+            AdminAccount::KEY_EMAIL => 'test@test.com',
+            AdminAccount::KEY_FIRST_NAME => 'John',
+            AdminAccount::KEY_LAST_NAME => 'Doe',
+            InitParamListener::BOOTSTRAP_PARAM => null,
+        ];
+        $commandTester = new CommandTester($this->command);
+        $installerMock = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $installerMock->expects($this->once())->method('installAdminUser')->with($data);
+        $this->installerFactoryMock->expects($this->once())->method('create')->willReturn($installerMock);
+        $commandTester->execute($options);
+        $this->assertEquals('Created admin user user' . PHP_EOL, $commandTester->getDisplay());
+    }
+
+    public function testGetOptionsList()
+    {
+        /* @var $argsList \Symfony\Component\Console\Input\InputArgument[] */
+        $argsList = $this->command->getOptionsList();
+        $this->assertEquals(AdminAccount::KEY_EMAIL, $argsList[2]->getName());
+    }
+
+    /**
+     * @dataProvider validateDataProvider
+     * @param bool[] $options
+     * @param string[] $errors
+     */
+    public function testValidate(array $options, array $errors)
+    {
+        $inputMock = $this->getMockForAbstractClass('Symfony\Component\Console\Input\InputInterface', [], '', false);
+        $index = 0;
+        foreach ($options as $option) {
+            $inputMock->expects($this->at($index++))->method('getOption')->willReturn($option);
+        }
+        $this->assertEquals($errors, $this->command->validate($inputMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateDataProvider()
+    {
+        return [
+            [[false, true, true, true, true], ['Missing option ' . AdminAccount::KEY_USER]],
+            [
+                [true, false, false, true, true],
+                ['Missing option ' . AdminAccount::KEY_PASSWORD, 'Missing option ' . AdminAccount::KEY_EMAIL],
+            ],
+            [[true, true, true, true, true], []],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
index 857ea54b8f51818c45f61b28e1a1792887b41e6b..11e08c4faf7784e8af19f186640dc30ef82b7461 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ConfigSetCommandTest.php
@@ -27,8 +27,6 @@ class ConfigSetCommandTest extends \PHPUnit_Framework_TestCase
      */
     private $command;
 
-
-
     public function setUp()
     {
         $option = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DbDataUpgradeCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbDataUpgradeCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..50494cd968b1ccf56db4596f6303f68eb8d59bf8
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbDataUpgradeCommandTest.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Framework\Module\ModuleList;
+use Magento\Setup\Console\Command\DbDataUpgradeCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class DbDataUpgradeCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Setup\Model\InstallerFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $installerFactory;
+
+    /**
+     * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $deploymentConfig;
+
+    protected function setup()
+    {
+        $this->installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
+    }
+
+    public function testExecute()
+    {
+        $this->deploymentConfig->expects($this->once())->method('isAvailable')->will($this->returnValue(true));
+        $installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $this->installerFactory->expects($this->once())->method('create')->will($this->returnValue($installer));
+        $installer->expects($this->once())->method('installDataFixtures');
+
+        $commandTester = new CommandTester(
+            new DbDataUpgradeCommand($this->installerFactory, $this->deploymentConfig)
+        );
+        $commandTester->execute([]);
+    }
+
+    public function testExecuteNoConfig()
+    {
+        $this->deploymentConfig->expects($this->once())->method('isAvailable')->will($this->returnValue(false));
+        $this->installerFactory->expects($this->never())->method('create');
+
+        $commandTester = new CommandTester(
+            new DbDataUpgradeCommand($this->installerFactory, $this->deploymentConfig)
+        );
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'No information is available: the application is not installed.%w',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DbSchemaUpgradeCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbSchemaUpgradeCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6300175f95926f4c476d23ecc9252ea545d819ec
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbSchemaUpgradeCommandTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Framework\Module\ModuleList;
+use Magento\Setup\Console\Command\DbSchemaUpgradeCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class DbSchemaUpgradeCommandTest extends DbDataUpgradeCommandTest
+{
+    public function testExecute()
+    {
+        $this->deploymentConfig->expects($this->once())->method('isAvailable')->will($this->returnValue(true));
+        $installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $this->installerFactory->expects($this->once())->method('create')->will($this->returnValue($installer));
+        $installer->expects($this->once())->method('installSchema');
+
+        $commandTester = new CommandTester(
+            new DbSchemaUpgradeCommand($this->installerFactory, $this->deploymentConfig)
+        );
+        $commandTester->execute([]);
+    }
+
+    public function testExecuteNoConfig()
+    {
+        $this->deploymentConfig->expects($this->once())->method('isAvailable')->will($this->returnValue(false));
+        $this->installerFactory->expects($this->never())->method('create');
+
+        $commandTester = new CommandTester(
+            new DbSchemaUpgradeCommand($this->installerFactory, $this->deploymentConfig)
+        );
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'No information is available: the application is not installed.%w',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DbStatusCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbStatusCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d16758b51e6c99d4437423e59564f0b095c8621c
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DbStatusCommandTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Framework\Module\DbVersionInfo;
+use Magento\Setup\Console\Command\DbStatusCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class DbStatusCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Module\DbVersionInfo|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dbVersionInfo;
+
+    /**
+     * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $deploymentConfig;
+
+    /**
+     * @var DbStatusCommand
+     */
+    private $command;
+
+    protected function setUp()
+    {
+        $this->dbVersionInfo = $this->getMock('Magento\Framework\Module\DbVersionInfo', [], [], '', false);
+        $objectManagerProvider = $this->getMock('Magento\Setup\Model\ObjectManagerProvider', [], [], '', false);
+        $objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
+        $objectManagerProvider->expects($this->any())
+            ->method('get')
+            ->will($this->returnValue($objectManager));
+        $objectManager->expects($this->any())
+            ->method('get')
+            ->will($this->returnValue($this->dbVersionInfo));
+        $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
+        $this->command = new DbStatusCommand($objectManagerProvider, $this->deploymentConfig);
+    }
+
+    /**
+     * @param array $outdatedInfo
+     * @param string $expectedMessage
+     *
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute(array $outdatedInfo, $expectedMessage)
+    {
+        $this->deploymentConfig->expects($this->once())
+            ->method('isAvailable')
+            ->will($this->returnValue(true));
+        $this->dbVersionInfo->expects($this->once())
+            ->method('getDbVersionErrors')
+            ->will($this->returnValue($outdatedInfo));
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+        $this->assertStringMatchesFormat($expectedMessage, $tester->getDisplay());
+    }
+
+    public function executeDataProvider()
+    {
+        return [
+            'DB is up to date' => [
+                [],
+                'All modules are up to date%a'
+            ],
+            'DB is outdated'   => [
+                [
+                    [
+                        DbVersionInfo::KEY_MODULE => 'module_a',
+                        DbVersionInfo::KEY_TYPE => 'schema',
+                        DbVersionInfo::KEY_CURRENT => '1.0.0',
+                        DbVersionInfo::KEY_REQUIRED => '2.0.0'
+                    ]
+                ],
+                '%amodule_a%aschema%a1%a->%a2'
+                . "%aRun 'setup:upgrade' to update your DB schema and data%a",
+            ],
+            'code is outdated' => [
+                [
+                    [
+                        DbVersionInfo::KEY_MODULE => 'module_a',
+                        DbVersionInfo::KEY_TYPE => 'data',
+                        DbVersionInfo::KEY_CURRENT => '2.0.0',
+                        DbVersionInfo::KEY_REQUIRED => '1.0.0'
+                    ]
+                ],
+                '%amodule_a%adata%a2.0.0%a->%a1.0.0'
+                . '%aSome modules use code versions newer or older than the database%a',
+            ],
+            'both DB and code is outdated' => [
+                [
+                    [
+                        DbVersionInfo::KEY_MODULE => 'module_a',
+                        DbVersionInfo::KEY_TYPE => 'schema',
+                        DbVersionInfo::KEY_CURRENT => '1.0.0',
+                        DbVersionInfo::KEY_REQUIRED => '2.0.0'
+                    ],
+                    [
+                        DbVersionInfo::KEY_MODULE => 'module_b',
+                        DbVersionInfo::KEY_TYPE => 'data',
+                        DbVersionInfo::KEY_CURRENT => '2.0.0',
+                        DbVersionInfo::KEY_REQUIRED => '1.0.0'
+                    ]
+                ],
+                '%amodule_a%aschema%a1.0.0%a->%a2.0.0'
+                . '%amodule_b%adata%a2.0.0%a->%a1.0.0'
+                . '%aSome modules use code versions newer or older than the database%a',
+            ],
+        ];
+    }
+
+    public function testExecuteNotInstalled()
+    {
+        $this->deploymentConfig->expects($this->once())
+            ->method('isAvailable')
+            ->will($this->returnValue(false));
+        $this->dbVersionInfo->expects($this->never())
+            ->method('getDbVersionErrors');
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+        $this->assertStringMatchesFormat(
+            'No information is available: the application is not installed.%w',
+            $tester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoCurrencyListCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoCurrencyListCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a7e087f94bd2b3f68ca6d01a767202d1873ebbd5
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoCurrencyListCommandTest.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InfoCurrencyListCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class InfoCurrencyListCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $currencies = [
+            'CUR' => 'Currency description'
+        ];
+
+        /** @var \Magento\Setup\Model\Lists|\PHPUnit_Framework_MockObject_MockObject $list */
+        $list = $this->getMock('Magento\Setup\Model\Lists', [], [], '', false);
+        $list->expects($this->once())->method('getCurrencyList')->will($this->returnValue($currencies));
+        $commandTester = new CommandTester(new InfoCurrencyListCommand($list));
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'CUR => Currency description',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoLanguageListCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoLanguageListCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..938fb53f72590df1a99758d588ffd2129f23a09a
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoLanguageListCommandTest.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InfoLanguageListCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class InfoLanguageListCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $languages = [
+            'LNG' => 'Language description'
+        ];
+        /** @var \Magento\Setup\Model\Lists|\PHPUnit_Framework_MockObject_MockObject $list */
+        $list = $this->getMock('Magento\Setup\Model\Lists', [], [], '', false);
+        $list->expects($this->once())->method('getLocaleList')->will($this->returnValue($languages));
+        $commandTester = new CommandTester(new InfoLanguageListCommand($list));
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'LNG => Language description',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoTimezoneListCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoTimezoneListCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b1be6a5e9bc122e58d4845d116de5a14bd13e51
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoTimezoneListCommandTest.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InfoTimezoneListCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class InfoTimezoneListCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $timezones = [
+            'timezone' => 'timezone description'
+        ];
+
+        /** @var \Magento\Setup\Model\Lists|\PHPUnit_Framework_MockObject_MockObject $list */
+        $list = $this->getMock('Magento\Setup\Model\Lists', [], [], '', false);
+        $list->expects($this->once())->method('getTimezoneList')->will($this->returnValue($timezones));
+        $commandTester = new CommandTester(new InfoTimezoneListCommand($list));
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'timezone => timezone description',
+            $commandTester->getDisplay()
+        );
+
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a358368092f032e951ecfcbba5d8f92a240367fd
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallCommandTest.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InstallCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+use Magento\Setup\Model\AdminAccount;
+use Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
+use Magento\Framework\Config\ConfigOptionsList as SetupConfigOptionsList;
+use Magento\Setup\Console\Command\InstallStoreConfigurationCommand;
+use Magento\Setup\Model\StoreConfigurationDataMapper;
+
+class InstallCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $input = [
+            '--' . SetupConfigOptionsList::INPUT_KEY_DB_HOST => 'localhost',
+            '--' . SetupConfigOptionsList::INPUT_KEY_DB_NAME => 'magento',
+            '--' . SetupConfigOptionsList::INPUT_KEY_DB_USER => 'root',
+            '--' . BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME => 'admin',
+            '--' . StoreConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/magento2ce/',
+            '--' . StoreConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
+            '--' . StoreConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
+            '--' . StoreConfigurationDataMapper::KEY_CURRENCY => 'USD',
+            '--' . AdminAccount::KEY_USER => 'user',
+            '--' . AdminAccount::KEY_PASSWORD => '123123q',
+            '--' . AdminAccount::KEY_EMAIL => 'test@test.com',
+            '--' . AdminAccount::KEY_FIRST_NAME => 'John',
+            '--' . AdminAccount::KEY_LAST_NAME => 'Doe',
+        ];
+
+        $configModel = $this->getMock('Magento\Setup\Model\ConfigModel', [], [], '', false);
+        $configModel
+            ->expects($this->exactly(2))
+            ->method('getAvailableOptions')
+            ->will($this->returnValue($this->getOptionsListDeployConfig()));
+        $configModel
+            ->expects($this->once())
+            ->method('validate')
+            ->will($this->returnValue([]));
+
+        $userConfig = $this->getMock(
+            'Magento\Setup\Console\Command\InstallStoreConfigurationCommand',
+            [],
+            [],
+            '',
+            false
+        );
+        $userConfig
+            ->expects($this->once())
+            ->method('getOptionsList')
+            ->will($this->returnValue($this->getOptionsListUserConfig()));
+
+        $adminUser = $this->getMock('Magento\Setup\Console\Command\AdminUserCreateCommand', [], [], '', false);
+        $adminUser
+            ->expects($this->once())
+            ->method('getOptionsList')
+            ->will($this->returnValue($this->getOptionsListAdminUser()));
+        $adminUser
+            ->expects($this->once())
+            ->method('validate')
+            ->will($this->returnValue([]));
+
+        $installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $installerFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($installer));
+        $installer->expects($this->once())->method('install');
+        $commandTester = new CommandTester(new InstallCommand(
+            $installerFactory,
+            $configModel,
+            $userConfig,
+            $adminUser
+        ));
+        $commandTester->execute($input);
+    }
+
+    /**
+     * Get list of options for deployment configuration
+     *
+     * @return array
+     */
+    private function getOptionsListDeployConfig()
+    {
+        $option1 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option1
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(SetupConfigOptionsList::INPUT_KEY_DB_HOST));
+        $option2 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option2
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(SetupConfigOptionsList::INPUT_KEY_DB_NAME));
+        $option3 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option3
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(SetupConfigOptionsList::INPUT_KEY_DB_USER));
+        $option4 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option4
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME));
+        return [$option1, $option2, $option3, $option4];
+    }
+
+    /**
+     * Get list of options for user configuration
+     *
+     * @return array
+     */
+    private function getOptionsListUserConfig()
+    {
+        $option1 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option1
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(StoreConfigurationDataMapper::KEY_BASE_URL));
+        $option2 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option2
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(StoreConfigurationDataMapper::KEY_LANGUAGE));
+        $option3 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option3
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(StoreConfigurationDataMapper::KEY_TIMEZONE));
+        $option4 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option4
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(StoreConfigurationDataMapper::KEY_CURRENCY));
+        return [$option1, $option2, $option3, $option4];
+    }
+
+    /**
+     * Get list of options for admin user
+     *
+     * @return array
+     */
+    private function getOptionsListAdminUser()
+    {
+        $option1 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option1
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(AdminAccount::KEY_USER));
+        $option2 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option2
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(AdminAccount::KEY_PASSWORD));
+        $option3 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option3
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(AdminAccount::KEY_EMAIL));
+        $option4 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option4
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(AdminAccount::KEY_FIRST_NAME));
+        $option5 = $this->getMock('Magento\Framework\Setup\Option\TextConfigOption', [], [], '', false);
+        $option5
+            ->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue(AdminAccount::KEY_LAST_NAME));
+        return [$option1, $option2, $option3, $option4, $option5];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..65e5ded76910b01334ae1e93134cfca621a8e9ec
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InstallStoreConfigurationCommandTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InstallStoreConfigurationCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class InstallStoreConfigurationCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $deploymentConfig;
+
+    /**
+     * @var \Magento\Setup\Model\InstallerFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $installerFactory;
+
+    /**
+     * @var Installer|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $installer;
+
+    /**
+     * @var InstallStoreConfigurationCommand
+     */
+    private $command;
+
+    protected function setUp()
+    {
+        $this->installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
+        $this->installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $this->command = new InstallStoreConfigurationCommand($this->installerFactory, $this->deploymentConfig);
+    }
+
+    public function testExecute()
+    {
+        $this->deploymentConfig->expects($this->once())
+            ->method('isAvailable')
+            ->will($this->returnValue(true));
+        $this->installer->expects($this->once())
+            ->method('installUserConfig');
+        $this->installerFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->installer));
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+    }
+
+    public function testExecuteNotInstalled()
+    {
+        $this->deploymentConfig->expects($this->once())
+            ->method('isAvailable')
+            ->will($this->returnValue(false));
+        $this->installerFactory->expects($this->never())
+            ->method('create');
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+        $this->assertStringMatchesFormat(
+            "Store settings can't be saved because the Magento application is not installed.%w",
+            $tester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceAllowIpsCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceAllowIpsCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b129552455218f84445a91f2d602c79326610be8
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceAllowIpsCommandTest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\MaintenanceAllowIpsCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class MaintenanceAllowIpsCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $maintenanceMode;
+
+    /**
+     * @var MaintenanceAllowIpsCommand
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false);
+        $this->command = new MaintenanceAllowIpsCommand($this->maintenanceMode);
+    }
+
+    /**
+     * @param array $input
+     * @param string $expectedMessage
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute(array $input, $expectedMessage)
+    {
+        if (isset($input['--none']) && !$input['--none'] && isset($input['ip'])) {
+            $this->maintenanceMode
+                ->expects($this->once())
+                ->method('getAddressInfo')
+                ->willReturn($input['ip']);
+        }
+        $tester = new CommandTester($this->command);
+        $tester->execute($input);
+        $this->assertEquals($expectedMessage, $tester->getDisplay());
+
+    }
+
+    /**
+     * return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                ['ip' => ['127.0.0.1', '127.0.0.2'], '--none' => false],
+                'Set exempt IP-addresses: 127.0.0.1, 127.0.0.2' . PHP_EOL
+            ],
+            [
+                ['--none' => true],
+                'Set exempt IP-addresses: none' . PHP_EOL
+            ],
+            [
+                ['ip' => ['127.0.0.1', '127.0.0.2'], '--none' => true],
+                'Set exempt IP-addresses: none' . PHP_EOL
+            ],
+            [
+                [],
+                ''
+            ]
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceDisableCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceDisableCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e32acacb15aaa7d23197b77e166941d636d1f95a
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceDisableCommandTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\MaintenanceDisableCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class MaintenanceDisableCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $maintenanceMode;
+
+    /**
+     * @var MaintenanceDisableCommand
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false);
+        $this->command = new MaintenanceDisableCommand($this->maintenanceMode);
+    }
+
+    /**
+     * @param array $input
+     * @param string $expectedMessage
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute(array $input, $expectedMessage)
+    {
+        $return = isset($input['--ip']) ? ($input['--ip'] !== ['none'] ? $input['--ip'] : []) : [];
+        $this->maintenanceMode
+            ->expects($this->any())
+            ->method('getAddressInfo')
+            ->willReturn($return);
+        $tester = new CommandTester($this->command);
+        $tester->execute($input);
+        $this->assertEquals($expectedMessage, $tester->getDisplay());
+    }
+
+    /**
+     * return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                ['--ip' => ['127.0.0.1', '127.0.0.2']],
+                'Disabled maintenance mode' . PHP_EOL .
+                'Set exempt IP-addresses: 127.0.0.1, 127.0.0.2' . PHP_EOL
+            ],
+            [
+                [],
+                'Disabled maintenance mode' . PHP_EOL
+            ],
+            [
+                ['--ip' => ['none']],
+                'Disabled maintenance mode' . PHP_EOL .
+                'Set exempt IP-addresses: none' . PHP_EOL
+            ],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceEnableCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceEnableCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7615de13c617e951cfb965c8390ff1e46444b76a
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceEnableCommandTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\MaintenanceEnableCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class MaintenanceEnableCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $maintenanceMode;
+
+    /**
+     * @var MaintenanceEnableCommand
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false);
+        $this->command = new MaintenanceEnableCommand($this->maintenanceMode);
+    }
+
+    /**
+     * @param array $input
+     * @param string $expectedMessage
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute(array $input, $expectedMessage)
+    {
+        $return = isset($input['--ip']) ? ($input['--ip'] !== ['none'] ? $input['--ip'] : []) : [];
+        $this->maintenanceMode
+            ->expects($this->any())
+            ->method('getAddressInfo')
+            ->willReturn($return);
+        $tester = new CommandTester($this->command);
+        $tester->execute($input);
+        $this->assertEquals($expectedMessage, $tester->getDisplay());
+
+    }
+
+    /**
+     * return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                ['--ip' => ['127.0.0.1', '127.0.0.2']],
+                'Enabled maintenance mode' . PHP_EOL .
+                'Set exempt IP-addresses: 127.0.0.1, 127.0.0.2' . PHP_EOL
+            ],
+            [
+                ['--ip' => ['none']],
+                'Enabled maintenance mode' . PHP_EOL .
+                'Set exempt IP-addresses: none' . PHP_EOL
+            ],
+            [
+                [],
+                'Enabled maintenance mode' . PHP_EOL
+            ],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceStatusCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceStatusCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8205bf8277b2c21e11861df672061398146939df
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/MaintenanceStatusCommandTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\MaintenanceStatusCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class MaintenanceStatusCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $maintenanceMode;
+
+    /**
+     * @var MaintenanceStatusCommand
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false);
+        $this->command = new MaintenanceStatusCommand($this->maintenanceMode);
+    }
+
+    /**
+     * @param array $maintenanceData
+     * @param string $expectedMessage
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute(array $maintenanceData, $expectedMessage)
+    {
+        $this->maintenanceMode->expects($this->once())->method('isOn')->willReturn($maintenanceData[0]);
+        $this->maintenanceMode->expects($this->once())->method('getAddressInfo')->willReturn($maintenanceData[1]);
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+        $this->assertEquals($expectedMessage, $tester->getDisplay());
+
+    }
+
+    /**
+     * return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                [true, ['127.0.0.1', '127.0.0.2']],
+                'Status: maintenance mode is active' . PHP_EOL .
+                'List of exempt IP-addresses: 127.0.0.1, 127.0.0.2' . PHP_EOL
+            ],
+            [
+                [true, []],
+                'Status: maintenance mode is active' . PHP_EOL . 'List of exempt IP-addresses: none' . PHP_EOL
+            ],
+            [
+                [false, []],
+                'Status: maintenance mode is not active' . PHP_EOL . 'List of exempt IP-addresses: none' . PHP_EOL
+            ],
+            [
+                [false, ['127.0.0.1', '127.0.0.2']],
+                'Status: maintenance mode is not active' . PHP_EOL .
+                'List of exempt IP-addresses: 127.0.0.1, 127.0.0.2' . PHP_EOL
+            ],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleEnableDisableCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleEnableDisableCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0fdb27794887177ecaee65f25d2d057ee3d97da
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleEnableDisableCommandTest.php
@@ -0,0 +1,278 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\ModuleDisableCommand;
+use Magento\Setup\Console\Command\ModuleEnableCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class ModuleEnableDisableCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Setup\Model\ObjectManagerProvider|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $objectManagerProvider;
+
+    /**
+     * @var \Magento\Framework\Module\Status|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $status;
+
+    /**
+     * @var \Magento\Framework\App\Cache|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cache;
+
+    /**
+     * @var \Magento\Framework\App\State\CleanupFiles|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cleanupFiles;
+
+    /**
+     * @var \Magento\Framework\Module\FullModuleList|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $fullModuleList;
+
+    protected function setUp()
+    {
+        $this->objectManagerProvider = $this->getMock('Magento\Setup\Model\ObjectManagerProvider', [], [], '', false);
+        $objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
+        $this->objectManagerProvider->expects($this->any())
+            ->method('get')
+            ->will($this->returnValue($objectManager));
+        $this->status = $this->getMock('Magento\Framework\Module\Status', [], [], '', false);
+        $this->cache = $this->getMock('Magento\Framework\App\Cache', [], [], '', false);
+        $this->cleanupFiles = $this->getMock('Magento\Framework\App\State\CleanupFiles', [], [], '', false);
+        $this->fullModuleList = $this->getMock('Magento\Framework\Module\FullModuleList', [], [], '', false);
+        $objectManager->expects($this->any())
+            ->method('get')
+            ->will($this->returnValueMap([
+                ['Magento\Framework\Module\Status', $this->status],
+                ['Magento\Framework\App\Cache', $this->cache],
+                ['Magento\Framework\App\State\CleanupFiles', $this->cleanupFiles],
+                ['Magento\Framework\Module\FullModuleList', $this->fullModuleList],
+            ]));
+    }
+
+    /**
+     * @param bool $isEnable
+     * @param bool $clearStaticContent
+     * @param string $expectedMessage
+     *
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute($isEnable, $clearStaticContent, $expectedMessage)
+    {
+        $this->status->expects($this->once())
+            ->method('getModulesToChange')
+            ->with($isEnable, ['Magento_Module1', 'Magento_Module2'])
+            ->will($this->returnValue(['Magento_Module1']));
+
+        $this->status->expects($this->any())
+            ->method('checkConstraints')
+            ->will($this->returnValue([]));
+
+        $this->status->expects($this->once())
+            ->method('setIsEnabled')
+            ->with($isEnable, ['Magento_Module1']);
+
+        $this->cache->expects($this->once())
+            ->method('clean');
+        $this->cleanupFiles->expects($this->once())
+            ->method('clearCodeGeneratedClasses');
+        $this->cleanupFiles->expects($clearStaticContent ? $this->once() : $this->never())
+            ->method('clearMaterializedViewFiles');
+
+        $commandTester = $isEnable
+            ? new CommandTester(new ModuleEnableCommand($this->objectManagerProvider))
+            : new CommandTester(new ModuleDisableCommand($this->objectManagerProvider));
+        $input = ['module' => ['Magento_Module1', 'Magento_Module2']];
+        if ($clearStaticContent) {
+            $input['--clear-static-content'] = true;
+        }
+        $commandTester->execute($input);
+        $this->assertStringMatchesFormat($expectedMessage, $commandTester->getDisplay());
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            'enable, do not clear static content' => [
+                true,
+                false,
+                '%amodules have been enabled%aMagento_Module1%aGenerated static view files were not cleared%a'
+            ],
+            'disable, do not clear static content' => [
+                false,
+                false,
+                '%amodules have been disabled%aMagento_Module1%aGenerated static view files were not cleared%a'
+            ],
+            'enable, clear static content' => [
+                true,
+                true,
+                '%amodules have been enabled%aMagento_Module1%aGenerated static view files cleared%a'
+            ],
+            'disable, clear static content' => [
+                false,
+                true,
+                '%amodules have been disabled%aMagento_Module1%aGenerated static view files cleared%a'
+            ],
+        ];
+    }
+
+    /**
+     * @param bool $isEnable
+     * @param string $expectedMessage
+     *
+     * @dataProvider executeAllDataProvider
+     */
+    public function testExecuteAll($isEnable, $expectedMessage)
+    {
+        $this->fullModuleList->expects($this->once())
+            ->method('getNames')
+            ->will($this->returnValue(['Magento_Module1', 'Magento_Module2']));
+
+        $this->status->expects($this->once())
+            ->method('getModulesToChange')
+            ->with($isEnable, ['Magento_Module1', 'Magento_Module2'])
+            ->will($this->returnValue(['Magento_Module1']));
+
+        $this->status->expects($this->any())
+            ->method('checkConstraints')
+            ->will($this->returnValue([]));
+
+        $this->status->expects($this->once())
+            ->method('setIsEnabled')
+            ->with($isEnable, ['Magento_Module1']);
+
+        $commandTester = $isEnable
+            ? new CommandTester(new ModuleEnableCommand($this->objectManagerProvider))
+            : new CommandTester(new ModuleDisableCommand($this->objectManagerProvider));
+        $input = ['--all' => true];
+        $commandTester->execute($input);
+        $this->assertStringMatchesFormat($expectedMessage, $commandTester->getDisplay());
+    }
+
+    /**
+     * @return array
+     */
+    public function executeAllDataProvider()
+    {
+        return [
+            'enable'  => [true, '%amodules have been enabled%aMagento_Module1%a'],
+            'disable' => [false, '%amodules have been disabled%aMagento_Module1%a'],
+        ];
+    }
+
+    /**
+     * @param bool $isEnable
+     *
+     * @dataProvider executeWithConstraintsDataProvider
+     */
+    public function testExecuteWithConstraints($isEnable)
+    {
+        $this->status->expects($this->once())
+            ->method('getModulesToChange')
+            ->with($isEnable, ['Magento_Module1', 'Magento_Module2'])
+            ->will($this->returnValue(['Magento_Module1']));
+
+        $this->status->expects($this->any())
+            ->method('checkConstraints')
+            ->will($this->returnValue(['constraint1', 'constraint2']));
+
+        $this->status->expects($this->never())
+            ->method('setIsEnabled');
+
+        $commandTester = $isEnable
+            ? new CommandTester(new ModuleEnableCommand($this->objectManagerProvider))
+            : new CommandTester(new ModuleDisableCommand($this->objectManagerProvider));
+        $commandTester->execute(['module' => ['Magento_Module1', 'Magento_Module2']]);
+        $this->assertStringMatchesFormat(
+            'Unable to change status of modules%aconstraint1%aconstraint2%a',
+            $commandTester->getDisplay()
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function executeWithConstraintsDataProvider()
+    {
+        return [
+            'enable'  => [true],
+            'disable' => [false],
+        ];
+    }
+
+    /**
+     * @param bool $isEnable
+     * @param string $expectedMessage
+     *
+     * @dataProvider executeExecuteForceDataProvider
+     */
+    public function testExecuteForce($isEnable, $expectedMessage)
+    {
+        $this->status->expects($this->once())
+            ->method('getModulesToChange')
+            ->with($isEnable, ['Magento_Module1', 'Magento_Module2'])
+            ->will($this->returnValue(['Magento_Module1']));
+
+        $this->status->expects($this->never())
+            ->method('checkConstraints');
+
+        $this->status->expects($this->once())
+            ->method('setIsEnabled')
+            ->with($isEnable, ['Magento_Module1']);
+
+        $commandTester = $isEnable
+            ? new CommandTester(new ModuleEnableCommand($this->objectManagerProvider))
+            : new CommandTester(new ModuleDisableCommand($this->objectManagerProvider));
+        $commandTester->execute(['module' => ['Magento_Module1', 'Magento_Module2'], '--force' => true]);
+        $this->assertStringMatchesFormat(
+            $expectedMessage . '%amodules might not function properly%a',
+            $commandTester->getDisplay()
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function executeExecuteForceDataProvider()
+    {
+        return [
+            'enable'  => [true, '%amodules have been enabled%aMagento_Module1%a'],
+            'disable' => [false, '%amodules have been disabled%aMagento_Module1%a'],
+        ];
+    }
+
+    /**
+     * @param bool $isEnable
+     *
+     * @dataProvider executeWithConstraintsDataProvider
+     */
+    public function testExecuteNoChanges($isEnable)
+    {
+        $this->status->expects($this->once())
+            ->method('getModulesToChange')
+            ->with($isEnable, ['Magento_Module1', 'Magento_Module2'])
+            ->will($this->returnValue([]));
+
+        $this->status->expects($this->never())
+            ->method('setIsEnabled');
+
+        $commandTester = $isEnable
+            ? new CommandTester(new ModuleEnableCommand($this->objectManagerProvider))
+            : new CommandTester(new ModuleDisableCommand($this->objectManagerProvider));
+        $commandTester->execute(['module' => ['Magento_Module1', 'Magento_Module2']]);
+        $this->assertStringMatchesFormat(
+            'No modules were changed%a',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleStatusCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleStatusCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2010188f4a8c552e88f95a8ffbe015617f5016db
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/ModuleStatusCommandTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\ModuleStatusCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class ModuleStatusCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $objectManagerProvider = $this->getMock('Magento\Setup\Model\ObjectManagerProvider', [], [], '', false);
+        $objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
+        $objectManagerProvider->expects($this->any())
+            ->method('get')
+            ->will($this->returnValue($objectManager));
+        $moduleList = $this->getMock('Magento\Framework\Module\ModuleList', [], [], '', false);
+        $fullModuleList = $this->getMock('Magento\Framework\Module\FullModuleList', [], [], '', false);
+        $objectManager->expects($this->any())
+            ->method('create')
+            ->will($this->returnValueMap([
+                ['Magento\Framework\Module\ModuleList', [], $moduleList],
+                ['Magento\Framework\Module\FullModuleList', [], $fullModuleList],
+            ]));
+        $moduleList->expects($this->any())
+            ->method('getNames')
+            ->will($this->returnValue(['Magento_Module1', 'Magento_Module2']));
+        $fullModuleList->expects($this->any())
+            ->method('getNames')
+            ->will($this->returnValue(['Magento_Module1', 'Magento_Module2', 'Magento_Module3']));
+        $commandTester = new CommandTester(new ModuleStatusCommand($objectManagerProvider));
+        $commandTester->execute([]);
+        $this->assertStringMatchesFormat(
+            'List of enabled modules%aMagento_Module1%aMagento_Module2%a'
+            . 'List of disabled modules%aMagento_Module3%a',
+            $commandTester->getDisplay()
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/UninstallCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/UninstallCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..14090e2388ea3d5cad1f1b5aa11ef8e45d78b7ce
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/UninstallCommandTest.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Model\InstallerFactory;
+use Magento\Setup\Console\Command\UninstallCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+use Magento\Setup\Model\Installer;
+
+class UninstallCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var InstallerFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $installerFactory;
+
+    /**
+     * @var Installer|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $installer;
+
+    /**
+     * @var UninstallCommand|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $command;
+
+    public function setUp()
+    {
+        $this->installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $this->installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $this->command = new UninstallCommand($this->installerFactory);
+    }
+
+    public function testExecuteInteractionYes()
+    {
+        $this->installer->expects($this->once())->method('uninstall');
+        $this->installerFactory->expects($this->once())->method('create')->will($this->returnValue($this->installer));
+
+        $this->checkInteraction(true);
+    }
+
+    public function testExecuteInteractionNo()
+    {
+        $this->installer->expects($this->exactly(0))->method('uninstall');
+        $this->installerFactory->expects($this->exactly(0))->method('create');
+
+        $this->checkInteraction(false);
+    }
+
+    public function checkInteraction($answer)
+    {
+        $question = $this->getMock('Symfony\Component\Console\Helper\QuestionHelper', [], [], '', false);
+        $question
+            ->expects($this->once())
+            ->method('ask')
+            ->will($this->returnValue($answer));
+
+        /** @var \Symfony\Component\Console\Helper\HelperSet|\PHPUnit_Framework_MockObject_MockObject $helperSet */
+        $helperSet = $this->getMock('Symfony\Component\Console\Helper\HelperSet', [], [], '', false);
+        $helperSet
+            ->expects($this->once())
+            ->method('get')
+            ->with('question')
+            ->will($this->returnValue($question));
+        $this->command->setHelperSet($helperSet);
+
+        $tester = new CommandTester($this->command);
+        $tester->execute([]);
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..41ed13c09d4e829435cbe392bd04b96e08397390
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/UpgradeCommandTest.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\UpgradeCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class UpgradeCommandTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecute()
+    {
+        $installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
+        $installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
+        $installer->expects($this->at(0))->method('updateModulesSequence');
+        $installer->expects($this->at(1))->method('installSchema');
+        $installer->expects($this->at(2))->method('installDataFixtures');
+        $installerFactory->expects($this->once())->method('create')->willReturn($installer);
+        $commandTester = new CommandTester(new UpgradeCommand($installerFactory));
+        $commandTester->execute([]);
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/CommandListTest.php b/setup/src/Magento/Setup/Test/Unit/Console/CommandListTest.php
index 3e0d5bd666a426f36004c7a99cd6d8d2f181286b..39e78dc660683bd3b555ed6553dfc9e09f591c63 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/CommandListTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/CommandListTest.php
@@ -28,9 +28,34 @@ class CommandListTest extends \PHPUnit_Framework_TestCase
 
     public function testGetCommands()
     {
-        $this->serviceManager->expects($this->at(0))
-            ->method('create')
-            ->with('Magento\Setup\Console\Command\ConfigSetCommand');
+        $commands = [
+            'Magento\Setup\Console\Command\AdminUserCreateCommand',
+            'Magento\Setup\Console\Command\ConfigSetCommand',
+            'Magento\Setup\Console\Command\DbDataUpgradeCommand',
+            'Magento\Setup\Console\Command\DbSchemaUpgradeCommand',
+            'Magento\Setup\Console\Command\DbStatusCommand',
+            'Magento\Setup\Console\Command\InfoCurrencyListCommand',
+            'Magento\Setup\Console\Command\InfoLanguageListCommand',
+            'Magento\Setup\Console\Command\InfoTimezoneListCommand',
+            'Magento\Setup\Console\Command\InstallCommand',
+            'Magento\Setup\Console\Command\InstallStoreConfigurationCommand',
+            'Magento\Setup\Console\Command\ModuleEnableCommand',
+            'Magento\Setup\Console\Command\ModuleDisableCommand',
+            'Magento\Setup\Console\Command\ModuleStatusCommand',
+            'Magento\Setup\Console\Command\MaintenanceAllowIpsCommand',
+            'Magento\Setup\Console\Command\MaintenanceDisableCommand',
+            'Magento\Setup\Console\Command\MaintenanceEnableCommand',
+            'Magento\Setup\Console\Command\MaintenanceStatusCommand',
+            'Magento\Setup\Console\Command\UpgradeCommand',
+            'Magento\Setup\Console\Command\UninstallCommand',
+        ];
+        $index = 0;
+        foreach ($commands as $command) {
+            $this->serviceManager->expects($this->at($index++))
+                ->method('create')
+                ->with($command);
+        }
+
         $this->commandList->getCommands();
     }
 }
diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/ConsoleControllerTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/ConsoleControllerTest.php
deleted file mode 100644
index 6a5abfd72e66e018024faefac3ebd3b965913e89..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Test/Unit/Controller/ConsoleControllerTest.php
+++ /dev/null
@@ -1,663 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Setup\Test\Unit\Controller;
-
-use \Magento\Setup\Controller\ConsoleController;
-
-use Magento\Framework\Module\DbVersionInfo;
-use Magento\Setup\Model\UserConfigurationDataMapper as UserConfig;
-
-class ConsoleControllerTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\ConsoleLogger
-     */
-    private $consoleLogger;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\Lists
-     */
-    private $options;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\Installer
-     */
-    private $installer;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\MaintenanceMode
-     */
-    private $maintenanceMode;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Zend\Mvc\MvcEvent
-     */
-    private $mvcEvent;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Zend\Console\Request
-     */
-    private $request;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Zend\Stdlib\Parameters
-     */
-    private $parameters;
-
-    /**
-     * @var ConsoleController
-     */
-    private $controller;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\ObjectManagerInterface
-     */
-    private $objectManager;
-
-    public function setUp()
-    {
-        $this->consoleLogger = $this->getMock('Magento\Setup\Model\ConsoleLogger', [], [], '', false);
-        $installerFactory = $this->getMock('Magento\Setup\Model\InstallerFactory', [], [], '', false);
-        $this->installer = $this->getMock('Magento\Setup\Model\Installer', [], [], '', false);
-        $installerFactory->expects($this->once())->method('create')->with($this->consoleLogger)->willReturn(
-            $this->installer
-        );
-        $this->options = $this->getMock('Magento\Setup\Model\Lists', [], [], '', false);
-        $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false);
-
-        $this->request = $this->getMock('Zend\Console\Request', [], [], '', false);
-        $response = $this->getMock('Zend\Console\Response', [], [], '', false);
-        $routeMatch = $this->getMock('Zend\Mvc\Router\RouteMatch', [], [], '', false);
-
-        $this->parameters= $this->getMock('Zend\Stdlib\Parameters', [], [], '', false);
-        $this->request->expects($this->any())->method('getParams')->willReturn($this->parameters);
-
-        $this->mvcEvent = $this->getMock('Zend\Mvc\MvcEvent', [], [], '', false);
-        $this->mvcEvent->expects($this->once())->method('setRequest')->with($this->request)->willReturn(
-            $this->mvcEvent
-        );
-        $this->mvcEvent->expects($this->once())->method('getRequest')->willReturn($this->request);
-        $this->mvcEvent->expects($this->once())->method('setResponse')->with($response)->willReturn($this->mvcEvent);
-        $routeMatch->expects($this->any())->method('getParam')->willReturn('not-found');
-        $this->mvcEvent->expects($this->any())->method('getRouteMatch')->willReturn($routeMatch);
-
-        $this->objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
-        $objectManagerProvider = $this->getMock('Magento\Setup\Model\ObjectManagerProvider', [], [], '', false);
-        $objectManagerProvider->expects($this->any())->method('get')->willReturn($this->objectManager);
-
-        $this->controller = new ConsoleController(
-            $this->consoleLogger,
-            $this->options,
-            $installerFactory,
-            $this->maintenanceMode,
-            $objectManagerProvider
-        );
-        $this->controller->setEvent($this->mvcEvent);
-        $this->controller->dispatch($this->request, $response);
-    }
-
-    public function testGetRouterConfig()
-    {
-        $controller = $this->controller;
-        $actualRoute = $controller::getRouterConfig();
-        foreach ($actualRoute as $route) {
-            $options = $route['options'];
-            $this->assertArrayHasKey('route', $options);
-            $this->assertArrayHasKey('defaults', $options);
-            $defaults = $options['defaults'];
-            $this->assertArrayHasKey('controller', $defaults);
-            $this->assertArrayHasKey('action', $defaults);
-        }
-    }
-
-    public function testSetEventManager()
-    {
-        $eventManager = $this->getMock('Zend\EventManager\EventManagerInterface');
-        $eventManager->expects($this->atLeastOnce())->method('attach');
-        $returnValue = $this->controller->setEventManager($eventManager);
-        $this->assertSame($returnValue, $this->controller);
-    }
-
-    public function testOnDispatch()
-    {
-        $returnValue = $this->controller->onDispatch($this->mvcEvent);
-        $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $returnValue);
-    }
-
-    public function testOnDispatchWithException()
-    {
-        $errorMessage = 'Missing route matches; unsure how to retrieve action';
-        $event = $this->getMock('Zend\Mvc\MvcEvent');
-        $exception = $this->getMock('Magento\Setup\Exception', ['getCode'], [$errorMessage]);
-        $event->expects($this->once())->method('getRouteMatch')->willThrowException($exception);
-        $this->consoleLogger->expects($this->once())->method('log')->with($errorMessage);
-        $this->controller->onDispatch($event);
-    }
-
-    public function testInstallAction()
-    {
-        $this->installer->expects($this->once())->method('install')->with($this->parameters);
-        $this->controller->installAction();
-    }
-
-    public function testInstallSchemaAction()
-    {
-        $this->installer->expects($this->once())->method('installSchema');
-        $this->controller->installSchemaAction();
-    }
-
-    public function testInstallDataAction()
-    {
-        $this->installer->expects($this->once())->method('installDataFixtures');
-        $this->controller->installDataAction();
-    }
-
-    public function testUpdateAction()
-    {
-        $this->installer->expects($this->at(0))->method('updateModulesSequence');
-        $this->installer->expects($this->at(1))->method('installSchema');
-        $this->installer->expects($this->at(2))->method('installDataFixtures');
-        $this->controller->updateAction();
-    }
-
-    /**
-     * @param array $outdated
-     * @param array $expected
-     *
-     * @dataProvider dbStatusActionDataProvider
-     */
-    public function testDbStatusAction(array $outdated, array $expected)
-    {
-        $dbVersionInfo = $this->getMock('\Magento\Framework\Module\DbVersionInfo', [], [], '', false);
-        $this->objectManager->expects($this->once())
-            ->method('get')
-            ->with('Magento\Framework\Module\DbVersionInfo')
-            ->will($this->returnValue($dbVersionInfo));
-        $dbVersionInfo->expects($this->once())
-            ->method('getDbVersionErrors')
-            ->will($this->returnValue($outdated));
-        foreach ($expected as $at => $message) {
-            $this->consoleLogger->expects($this->at($at))
-                ->method('log')
-                ->with($this->matches($message));
-        }
-        $this->controller->dbStatusAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function dbStatusActionDataProvider()
-    {
-        return [
-            'one outdated module' => [
-                [[
-                    DbVersionInfo::KEY_MODULE => 'Module_One',
-                    DbVersionInfo::KEY_TYPE => 'schema',
-                    DbVersionInfo::KEY_CURRENT => '1.0.0',
-                    DbVersionInfo::KEY_REQUIRED => '1.0.1',
-                ]],
-                [
-                    1 => '%wModule_One%wschema:%w1.0.0%w->%w1.0.1%w',
-                    2 => 'Run the "Update" command to update your DB schema and data'
-                ],
-            ],
-            'no outdated modules' => [
-                [],
-                [0 => 'All modules are up to date'],
-            ],
-            'one newer module' => [
-                [[
-                    DbVersionInfo::KEY_MODULE => 'Module_One',
-                    DbVersionInfo::KEY_TYPE => 'schema',
-                    DbVersionInfo::KEY_CURRENT => '1.0.1',
-                    DbVersionInfo::KEY_REQUIRED => '1.0.0',
-                ]],
-                [
-                    1 => '%wModule_One%wschema:%w1.0.1%w->%w1.0.0%w',
-                    2 => 'Some modules use code versions newer or older than the database. ' .
-                        'First update the module code, then run the "Update" command.'
-                ],
-            ],
-            'one none module' => [
-                [[
-                    DbVersionInfo::KEY_MODULE => 'Module_One',
-                    DbVersionInfo::KEY_TYPE => 'schema',
-                    DbVersionInfo::KEY_CURRENT => 'none',
-                    DbVersionInfo::KEY_REQUIRED => '1.0.0',
-                ]],
-                [
-                    1 => '%wModule_One%wschema:%wnone%w->%w1.0.0%w',
-                    2 => 'Run the "Update" command to update your DB schema and data'
-                ],
-            ]
-        ];
-    }
-
-    public function testInstallUserConfigAction()
-    {
-        $this->installer->expects($this->once())->method('installUserConfig')->with($this->parameters);
-        $this->controller->installUserConfigAction();
-    }
-
-    public function testInstallAdminUserAction()
-    {
-        $this->installer->expects($this->once())->method('installAdminUser')->with($this->parameters);
-        $this->controller->installAdminUserAction();
-    }
-
-    public function testUninstallAction()
-    {
-        $this->installer->expects($this->once())->method('uninstall');
-        $this->controller->uninstallAction();
-    }
-
-    /**
-     * @param int $maintenanceMode
-     * @param int $setCount
-     * @param int $logCount
-     *
-     * @dataProvider maintenanceActionDataProvider
-     */
-    public function testMaintenanceAction($maintenanceMode, $setCount, $logCount)
-    {
-        $mapGetParam = [
-            ['set', null, $maintenanceMode],
-            ['addresses', null, null],
-        ];
-        $this->request->expects($this->exactly(2))->method('getParam')->will($this->returnValueMap($mapGetParam));
-        $this->maintenanceMode->expects($this->exactly($setCount))->method('set');
-        $this->maintenanceMode->expects($this->exactly(0))->method('setAddresses');
-        $this->maintenanceMode->expects($this->once())->method('isOn')->willReturn($maintenanceMode);
-        $this->maintenanceMode->expects($this->once())->method('getAddressInfo')->willReturn([]);
-        $this->consoleLogger->expects($this->exactly($logCount))->method('log');
-        $this->controller->maintenanceAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function maintenanceActionDataProvider()
-    {
-        return [
-            [1, 1, 2],
-            [0, 1, 2],
-            [null, 0, 1],
-        ];
-    }
-
-    /**
-     * @param array $addresses
-     * @param int $logCount
-     * @param int $setAddressesCount
-     *
-     * @dataProvider maintenanceActionWithAddressDataProvider
-     */
-    public function testMaintenanceActionWithAddress($addresses, $logCount, $setAddressesCount)
-    {
-        $mapGetParam = [
-            ['set', null, true],
-            ['addresses', null, $addresses],
-        ];
-        $this->request->expects($this->exactly(2))->method('getParam')->will($this->returnValueMap($mapGetParam));
-        $this->maintenanceMode->expects($this->exactly(1))->method('set');
-        $this->maintenanceMode->expects($this->exactly($setAddressesCount))->method('setAddresses');
-        $this->maintenanceMode->expects($this->once())->method('isOn')->willReturn(true);
-        $this->maintenanceMode->expects($this->once())->method('getAddressInfo')->willReturn($addresses);
-        $this->consoleLogger->expects($this->exactly($logCount))->method('log');
-        $this->controller->maintenanceAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function maintenanceActionWithAddressDataProvider()
-    {
-        return [
-            [['address1', 'address2'], 3, 1],
-            [[], 2, 1],
-            [null, 2, 0],
-        ];
-    }
-
-    /**
-     * @param string $type
-     * @param string $method
-     * @param array $expectedValue
-     *
-     * @dataProvider helpActionForLanguageCurrencyTimezoneDataProvider
-     */
-    public function testHelpActionForLanguageCurrencyTimezone($type, $method, $expectedValue)
-    {
-        $this->request->expects($this->once())->method('getParam')->willReturn($type);
-        $this->options->expects($this->once())->method($method)->willReturn($expectedValue);
-        $returnValue = $this->controller->helpAction();
-
-        //Need to convert from String to associative array.
-        $result = explode("\n", trim($returnValue));
-        $actual = [];
-        foreach ($result as $value) {
-            $tempArray  = explode(' => ', $value);
-            $actual[$tempArray[0]] = $tempArray[1];
-        }
-
-        $this->assertSame($expectedValue, $actual);
-    }
-
-    /**
-     * @return array
-     */
-    public function helpActionForLanguageCurrencyTimezoneDataProvider()
-    {
-        return [
-            [UserConfig::KEY_LANGUAGE, 'getLocaleList', [
-                    'someCode1' => 'some country',
-                    'someCode2' => 'some country2',
-                ]
-            ],
-            [UserConfig::KEY_CURRENCY, 'getCurrencyList', [
-                    'currencyCode1' => 'some currency1',
-                    'currencyCode2' => 'some currency2',
-                ]
-            ],
-            [UserConfig::KEY_TIMEZONE, 'getTimezoneList', [
-                    'timezone1' => 'some specific timezone1',
-                    'timezone2' => 'some specific timezone2',
-                ]
-            ],
-        ];
-    }
-
-    public function testHelpActionForModuleList()
-    {
-        $this->request->expects($this->once())->method('getParam')->willReturn(ConsoleController::HELP_LIST_OF_MODULES);
-        $moduleListMock = $this->getMock('Magento\Framework\Module\ModuleList', [], [], '', false);
-        $moduleListMock
-            ->expects($this->once())
-            ->method('getNames')
-            ->will($this->returnValue(['Magento_Theme', 'Magento_Store']));
-        $fullModuleListMock = $this->getMock('Magento\Framework\Module\FullModuleList', [], [], '', false);
-        $fullModuleListMock
-            ->expects($this->once())
-            ->method('getNames')
-            ->will($this->returnValue(['Magento_Theme', 'Magento_Store', 'Magento_Directory']));
-        $returnValueMap = [
-            [
-                'Magento\Framework\Module\ModuleList',
-                [],
-                $moduleListMock,
-            ],
-            [
-                'Magento\Framework\Module\FullModuleList',
-                [],
-                $fullModuleListMock,
-            ],
-        ];
-        $this->objectManager->expects($this->exactly(2))
-            ->method('create')
-            ->will($this->returnValueMap($returnValueMap));
-        $this->controller->helpAction();
-    }
-
-    public function testHelpActionNoType()
-    {
-        $beginHelpString = "\n==-------------------==\n"
-            . "   Magento Setup CLI   \n"
-            . "==-------------------==\n";
-        $this->request->expects($this->once())->method('getParam')->willReturn(false);
-        $returnValue = $this->controller->helpAction();
-        $this->assertStringStartsWith($beginHelpString, $returnValue);
-    }
-
-    /**
-     * @param string $command
-     * @param string $modules
-     * @param bool $isForce
-     * @param bool $expectedIsEnabled
-     * @param string[] $expectedModules
-     * @dataProvider moduleActionDataProvider
-     */
-    public function testModuleAction($command, $modules, $isForce, $expectedIsEnabled, $expectedModules)
-    {
-        $status = $this->getModuleActionMocks($command, $modules, $isForce, false);
-        $status->expects($this->once())->method('getModulesToChange')->willReturn($expectedModules);
-        if (!$isForce) {
-            $status->expects($this->once())->method('checkConstraints')->willReturn([]);
-        }
-        $status->expects($this->once())
-            ->method('setIsEnabled')
-            ->with($expectedIsEnabled, $expectedModules);
-        $this->consoleLogger->expects($this->once())->method('log');
-        $this->controller->moduleAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function moduleActionDataProvider()
-    {
-        return [
-            [ConsoleController::CMD_MODULE_ENABLE, 'Module_Foo,Module_Bar', false, true, ['Module_Foo', 'Module_Bar']],
-            [ConsoleController::CMD_MODULE_ENABLE, 'Module_Foo,Module_Bar', true, true, ['Module_Foo', 'Module_Bar']],
-            [ConsoleController::CMD_MODULE_DISABLE, 'Module_Foo', false, false, ['Module_Foo']],
-            [ConsoleController::CMD_MODULE_DISABLE, 'Module_Bar', true, false, ['Module_Bar']],
-        ];
-    }
-
-    /**
-     * @param string $command
-     * @param string $modules
-     * @param bool $isForce
-     * @param bool $expectedIsEnabled
-     * @param string[] $expectedModules
-     * @dataProvider moduleActionEnabledSuggestionMessageDataProvider
-     */
-    public function testModuleActionEnabledSuggestionMessage(
-        $command,
-        $modules,
-        $isForce,
-        $expectedIsEnabled,
-        $expectedModules
-    ) {
-        $status = $this->getModuleActionMocks($command, $modules, $isForce, false);
-        $status->expects($this->once())->method('getModulesToChange')->willReturn($expectedModules);
-        if (!$isForce) {
-            $status->expects($this->once())->method('checkConstraints')->willReturn([]);
-        }
-        $status->expects($this->once())
-            ->method('setIsEnabled')
-            ->with($expectedIsEnabled, $expectedModules);
-        $this->consoleLogger->expects($this->once())
-            ->method('log')
-            ->with($this->stringContains(
-                "To make sure that the enabled modules are properly registered, run 'update' command."
-            ));
-        $this->controller->moduleAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function moduleActionEnabledSuggestionMessageDataProvider()
-    {
-        return [
-            [ConsoleController::CMD_MODULE_ENABLE, 'Module_Foo,Module_Bar', false, true, ['Module_Foo', 'Module_Bar']],
-            [ConsoleController::CMD_MODULE_ENABLE, 'Module_Foo,Module_Bar', true, true, ['Module_Foo', 'Module_Bar']],
-            [ConsoleController::CMD_MODULE_ENABLE, 'Module_Foo,Module_Bar', false, true, ['Module_Foo']],
-        ];
-    }
-
-    /**
-     * @param string $command
-     * @param string $modules
-     * @param bool $isForce
-     * @param bool $expectedIsEnabled
-     * @param string[] $expectedModules
-     * @dataProvider moduleActionDataProvider
-     */
-    public function testModuleActionNoChanges($command, $modules, $isForce, $expectedIsEnabled, $expectedModules)
-    {
-        $status = $this->getModuleActionMocks($command, $modules, $isForce, true);
-        $status->expects($this->once())
-            ->method('getModulesToChange')
-            ->with($expectedIsEnabled, $expectedModules)
-            ->willReturn([]);
-        $status->expects($this->never())->method('checkConstraints');
-        $status->expects($this->never())->method('setIsEnabled');
-        $this->consoleLogger->expects($this->once())->method('log');
-        $this->controller->moduleAction();
-    }
-
-    /**
-     * @param string $command
-     * @param string $modules
-     * @param bool $isForce
-     * @param bool $expectedIsEnabled
-     * @param string[] $modulesToChange
-     * @dataProvider moduleActionPartialNoChangesDataProvider
-     */
-    public function testModuleActionPartialNoChanges(
-        $command,
-        $modules,
-        $isForce,
-        $expectedIsEnabled,
-        $modulesToChange
-    ) {
-        $status = $this->getModuleActionMocks($command, $modules, $isForce, false);
-        $status->expects($this->once())->method('getModulesToChange')->willReturn($modulesToChange);
-        if (!$isForce) {
-            $status->expects($this->once())->method('checkConstraints')->willReturn([]);
-        }
-        $status->expects($this->once())
-            ->method('setIsEnabled')
-            ->with($expectedIsEnabled, $modulesToChange);
-        $this->consoleLogger->expects($this->once())->method('log');
-        $this->controller->moduleAction();
-    }
-
-    /**
-     * @return array
-     */
-    public function moduleActionPartialNoChangesDataProvider()
-    {
-        return [
-            [
-                ConsoleController::CMD_MODULE_ENABLE,
-                'Module_Foo,Module_Bar',
-                false,
-                true,
-                ['Module_Bar'],
-            ],
-            [
-                ConsoleController::CMD_MODULE_ENABLE,
-                'Module_Foo,Module_Bar',
-                true,
-                true,
-                ['Module_Bar'],
-            ],
-            [
-                ConsoleController::CMD_MODULE_DISABLE,
-                'Module_Foo,Module_Bar',
-                false,
-                false,
-                ['Module_Bar'],
-            ],
-            [
-                ConsoleController::CMD_MODULE_DISABLE,
-                'Module_Foo,Module_Bar',
-                true,
-                false,
-                ['Module_Bar'],
-            ],
-        ];
-    }
-
-    /**
-     * Prepares a set of mocks for testing module action
-     *
-     * @param string $command
-     * @param string $modules
-     * @param bool $isForce
-     * @param bool $isUnchanged
-     * @return \PHPUnit_Framework_MockObject_MockObject
-     */
-    private function getModuleActionMocks($command, $modules, $isForce, $isUnchanged)
-    {
-        $this->request->expects($this->at(0))->method('getParam')->with(0)->willReturn($command);
-        $this->request->expects($this->at(1))->method('getParam')->with('modules')->willReturn($modules);
-        if (!$isUnchanged) {
-            $this->request->expects($this->at(2))->method('getParam')->with('force')->willReturn($isForce);
-        }
-        $status = $this->getMock('Magento\Framework\Module\Status', [], [], '', false);
-        $this->objectManager->expects($this->once())
-            ->method('create')
-            ->will($this->returnValue($status));
-        return $status;
-    }
-
-    /**
-     * @expectedException \Magento\Setup\Exception
-     * @expectedExceptionMessage Unable to change status of modules because of the following constraints:
-     */
-    public function testModuleActionNotAllowed()
-    {
-        $status = $this->getModuleActionMocks(
-            ConsoleController::CMD_MODULE_ENABLE,
-            'Module_Foo,Module_Bar',
-            false,
-            false
-        );
-        $status->expects($this->once())->method('getModulesToChange')->willReturn(['Module_Foo', 'Module_Bar']);
-        $status->expects($this->once())
-            ->method('checkConstraints')
-            ->willReturn(['Circular dependency of Foo and Bar']);
-        $status->expects($this->never())->method('setIsEnabled');
-        $this->controller->moduleAction();
-    }
-
-    /**
-     * @param string $option
-     * @param string $noParameters
-     *
-     * @dataProvider helpActionDataProvider
-     */
-    public function testHelpAction($option, $noParameters)
-    {
-        $this->request->expects($this->once())->method('getParam')->willReturn($option);
-        
-        $usage = $this->controller->getCommandUsage();
-        $expectedValue = explode(' ', (strlen($usage[$option]) > 0 ? $usage[$option] : $noParameters));
-        $returnValue = explode(
-            ' ',
-            trim(str_replace([PHP_EOL, 'Available parameters:'], '', $this->controller->helpAction()))
-        );
-        $expectedValue = asort($expectedValue);
-        $returnValue = asort($returnValue);
-        $this->assertEquals($expectedValue, $returnValue);
-    }
-
-    /**
-     * @return array
-     */
-    public function helpActionDataProvider()
-    {
-        $noParameters = 'This command has no parameters.';
-        return [
-            ['install',''],
-            ['update', $noParameters],
-            ['uninstall', $noParameters],
-            ['install-schema', $noParameters],
-            ['install-data', $noParameters],
-            ['install-user-configuration', ''],
-            ['install-admin-user', ''],
-            ['maintenance', ''],
-            ['help', ''],
-        ];
-    }
-}
diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/ModulesTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/ModulesTest.php
index 1607eebca1f174e42adbdf5936c7c9af878ac91d..96a30e19ac7a847092e8c1211c0e3f52f55d5c3e 100644
--- a/setup/src/Magento/Setup/Test/Unit/Controller/ModulesTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Controller/ModulesTest.php
@@ -35,7 +35,6 @@ class ModulesTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $this->objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
-        $this->status = $this->getMock('Magento\Framework\Module\Status', [], [], '', false);
         /** @var
          * $objectManagerProvider \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Model\ObjectManagerProvider
          */
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/AdminAccountTest.php b/setup/src/Magento/Setup/Test/Unit/Model/AdminAccountTest.php
index 938c72b9b2693f89975184f03958aa04fb0dc467..598641f1b844c84309a107b93c109ba0a88ab3d9 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/AdminAccountTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/AdminAccountTest.php
@@ -58,7 +58,7 @@ class AdminAccountTest extends \PHPUnit_Framework_TestCase
             AdminAccount::KEY_LAST_NAME => 'Doe',
             AdminAccount::KEY_EMAIL => 'john.doe@test.com',
             AdminAccount::KEY_PASSWORD => '123123q',
-            AdminAccount::KEY_USERNAME => 'admin',
+            AdminAccount::KEY_USER => 'admin',
         ];
 
         $this->adminAccount = new AdminAccount($this->setUpMock, $this->randomMock, $data);
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConsoleLoggerTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConsoleLoggerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..af381ada33f4db5564b64cc1ad1cfe359c3a68ac
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Model/ConsoleLoggerTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Model;
+
+use Magento\Setup\Model\ConsoleLogger;
+
+class ConsoleLoggerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\Console\Output\OutputInterface
+     */
+    private $console;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject |\Magento\Setup\Model\ConsoleLogger
+     */
+    private $consoleLoggerModel;
+
+    public function setUp()
+    {
+        $this->console = $this->getMock('Symfony\Component\Console\Output\OutputInterface', [], [], '', false);
+        $outputFormatter = $this->getMock(
+            'Symfony\Component\Console\Formatter\OutputFormatterInterface',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->console
+            ->expects($this->once())
+            ->method('getFormatter')
+            ->willReturn($outputFormatter);
+        $this->consoleLoggerModel = new ConsoleLogger($this->console);
+    }
+
+    public function testLogSuccess()
+    {
+        $this->console
+            ->expects($this->once())
+            ->method('writeln')
+            ->with('<info>[SUCCESS]: Success message.</info>');
+        $this->consoleLoggerModel->logSuccess('Success message.');
+    }
+
+    public function testLogError()
+    {
+        $exception = $this->getMock('\Exception', [], [], '', false);
+        $this->console
+            ->expects($this->once())
+            ->method('writeln')
+            ->with('<error>[ERROR]: </error>');
+        $this->consoleLoggerModel->logError($exception);
+    }
+
+    public function testLog()
+    {
+        $this->console
+            ->expects($this->once())
+            ->method('writeln')
+            ->with('<detail>Detail message.</detail>');
+        $this->consoleLoggerModel->log('Detail message.');
+    }
+
+    public function testLogInline()
+    {
+        $this->console
+            ->expects($this->once())
+            ->method('write')
+            ->with('<detail>Detail message.</detail>');
+        $this->consoleLoggerModel->logInline('Detail message.');
+    }
+
+    public function testLogMeta()
+    {
+        $this->console
+            ->expects($this->once())
+            ->method('writeln')
+            ->with('<metadata>Meta message.</metadata>');
+        $this->consoleLoggerModel->logMeta('Meta message.');
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/InstallerFactoryTest.php b/setup/src/Magento/Setup/Test/Unit/Model/InstallerFactoryTest.php
index b211b970509dd0b5bba1e6aeb23cf04d9152b6b8..291fee230a4bc3e33bd60c1d0cb16fee12bd2df5 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/InstallerFactoryTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/InstallerFactoryTest.php
@@ -73,6 +73,10 @@ class InstallerFactoryTest extends \PHPUnit_Framework_TestCase
                 'Magento\Setup\Model\ConfigModel',
                 $this->getMock('Magento\Setup\Model\ConfigModel', [], [], '', false),
             ],
+            [
+                'Magento\Framework\App\State\CleanupFiles',
+                $this->getMock('Magento\Framework\App\State\CleanupFiles', [], [], '', false),
+            ],
         ];
         $serviceLocatorMock = $this->getMockForAbstractClass('Zend\ServiceManager\ServiceLocatorInterface', ['get']);
         $serviceLocatorMock
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
index 2423d8c903342da47c4b165d772771a8dda64c7c..553c5c8ed4c1ec544a824a240237a1b0eb505dca 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
@@ -9,10 +9,10 @@ namespace Magento\Setup\Test\Unit\Model;
 use Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
 use Magento\Framework\Config\ConfigOptionsList as SetupConfigOptionsList;
 use \Magento\Setup\Model\Installer;
-use Magento\Framework\Config\ConfigOptionsList;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filesystem\DriverPool;
 use Magento\Framework\Config\File\ConfigFilePool;
+use Magento\Framework\App\State\CleanupFiles;
 
 /**
  * @SuppressWarnings(PHPMD.TooManyFields)
@@ -105,6 +105,11 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
      */
     private $configModel;
 
+    /**
+     * @var CleanupFiles|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cleanupFiles;
+
     /**
      * Sample DB configuration segment
      *
@@ -117,7 +122,7 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
                 SetupConfigOptionsList::KEY_HOST => '127.0.0.1',
                 SetupConfigOptionsList::KEY_NAME => 'magento',
                 SetupConfigOptionsList::KEY_USER => 'magento',
-                SetupConfigOptionsList::KEY_PASS => '',
+                SetupConfigOptionsList::KEY_PASSWORD => '',
             ],
         ],
     ];
@@ -153,6 +158,7 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
         $this->objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface');
         $this->contextMock = $this->getMock('Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
         $this->configModel = $this->getMock('Magento\Setup\Model\ConfigModel', [], [], '', false);
+        $this->cleanupFiles = $this->getMock('Magento\Framework\App\State\CleanupFiles', [], [], '', false);
         $this->object = $this->createObject();
     }
 
@@ -189,7 +195,8 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
             $this->sampleData,
             $objectManagerProvider,
             $this->contextMock,
-            $this->configModel
+            $this->configModel,
+            $this->cleanupFiles
         );
     }
 
@@ -300,18 +307,27 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
 
     public function testUpdateModulesSequence()
     {
-        $varDir = $this->getMockForAbstractClass('Magento\Framework\Filesystem\Directory\WriteInterface');
-        $varDir->expects($this->exactly(2))->method('getAbsolutePath')->willReturn('/var');
-        $this->filesystem
-            ->expects($this->exactly(2))
-            ->method('getDirectoryWrite')
-            ->willReturn($varDir);
-
         $allModules = [
             'Foo_One' => [],
             'Bar_Two' => [],
             'New_Module' => [],
         ];
+        $this->cleanupFiles->expects($this->once())->method('clearCodeGeneratedClasses')->will(
+            $this->returnValue(
+                [
+                    "The directory '/generation' doesn't exist - skipping cleanup",
+                ]
+            )
+        );
+
+        $cache = $this->getMock('Magento\Framework\App\Cache', [], [], '', false);
+        $cache->expects($this->once())->method('clean');
+        $this->objectManager->expects($this->once())
+            ->method('create')
+            ->will($this->returnValueMap([
+                ['Magento\Framework\App\Cache', [], $cache],
+            ]));
+
         $this->moduleLoader->expects($this->once())->method('load')->willReturn($allModules);
 
         $expectedModules = [
@@ -330,9 +346,10 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
         $this->configReader->expects($this->once())->method('load')
             ->willReturn(['modules' => ['Bar_Two' => 0, 'Foo_One' => 1, 'Old_Module' => 0] ]);
         $this->configWriter->expects($this->once())->method('saveConfig')->with($expectedModules);
-        $this->logger->expects($this->at(0))->method('log')->with('File system cleanup:');
-        $this->logger->expects($this->at(1))->method('log')
-            ->with('The directory \'/var\' doesn\'t exist - skipping cleanup');
+        $this->logger->expects($this->at(0))->method('log')->with('Cache cleared successfully');
+        $this->logger->expects($this->at(1))->method('log')->with('File system cleanup:');
+        $this->logger->expects($this->at(2))->method('log')
+            ->with('The directory \'/generation\' doesn\'t exist - skipping cleanup');
         $this->logger->expects($this->at(3))->method('log')->with('Updating modules:');
         $newObject->updateModulesSequence();
     }
@@ -340,18 +357,12 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
     public function testUninstall()
     {
         $this->config->expects($this->once())->method('isAvailable')->willReturn(false);
-        $varDir = $this->getMockForAbstractClass('Magento\Framework\Filesystem\Directory\WriteInterface');
-        $varDir->expects($this->once())->method('getAbsolutePath')->willReturn('/var');
-        $staticDir = $this->getMockForAbstractClass('Magento\Framework\Filesystem\Directory\WriteInterface');
-        $staticDir->expects($this->once())->method('getAbsolutePath')->willReturn('/static');
         $configDir = $this->getMockForAbstractClass('Magento\Framework\Filesystem\Directory\WriteInterface');
         $configDir->expects($this->once())->method('getAbsolutePath')->willReturn('/config/config.php');
         $this->filesystem
             ->expects($this->any())
             ->method('getDirectoryWrite')
             ->will($this->returnValueMap([
-                [DirectoryList::VAR_DIR, DriverPool::FILE, $varDir],
-                [DirectoryList::STATIC_VIEW, DriverPool::FILE, $staticDir],
                 [DirectoryList::CONFIG, DriverPool::FILE, $configDir],
             ]));
         $this->logger->expects($this->at(0))->method('log')->with('Starting Magento uninstallation:');
@@ -359,20 +370,36 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
             ->expects($this->at(1))
             ->method('log')
             ->with('No database connection defined - skipping database cleanup');
-        $this->logger->expects($this->at(2))->method('log')->with('File system cleanup:');
+        $cache = $this->getMock('Magento\Framework\App\Cache', [], [], '', false);
+        $cache->expects($this->once())->method('clean');
+        $this->objectManager->expects($this->once())
+            ->method('create')
+            ->will($this->returnValueMap([
+                ['Magento\Framework\App\Cache', [], $cache],
+            ]));
+        $this->logger->expects($this->at(2))->method('log')->with('Cache cleared successfully');
+        $this->logger->expects($this->at(3))->method('log')->with('File system cleanup:');
         $this->logger
-            ->expects($this->at(3))
+            ->expects($this->at(4))
             ->method('log')
             ->with("The directory '/var' doesn't exist - skipping cleanup");
         $this->logger
-            ->expects($this->at(4))
+            ->expects($this->at(5))
             ->method('log')
             ->with("The directory '/static' doesn't exist - skipping cleanup");
         $this->logger
-            ->expects($this->at(5))
+            ->expects($this->at(6))
             ->method('log')
             ->with("The file '/config/config.php' doesn't exist - skipping cleanup");
         $this->logger->expects($this->once())->method('logSuccess')->with('Magento uninstallation complete.');
+        $this->cleanupFiles->expects($this->once())->method('clearAllFiles')->will(
+            $this->returnValue(
+                [
+                    "The directory '/var' doesn't exist - skipping cleanup",
+                    "The directory '/static' doesn't exist - skipping cleanup"
+                ]
+            )
+        );
 
         $this->object->uninstall();
     }
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/StoreConfigurationDataMapperTest.php b/setup/src/Magento/Setup/Test/Unit/Model/StoreConfigurationDataMapperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9385ce4105e405cf38a9d1c9f4df8705ed6a5c90
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Model/StoreConfigurationDataMapperTest.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Model;
+
+use \Magento\Setup\Model\StoreConfigurationDataMapper;
+
+use Magento\Backend\Model\Url;
+use Magento\Directory\Helper\Data;
+use Magento\Directory\Model\Currency;
+use Magento\Setup\Module\Setup;
+use Magento\Store\Model\Store;
+
+class StoreConfigurationDataMapperTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @param array $data
+     * @param array $expected
+     * @dataProvider getConfigDataDataProvider
+     */
+    public function testGetConfigData(array $data, array $expected)
+    {
+        $userConfigurationDataMapper = new StoreConfigurationDataMapper();
+        $this->assertEquals($expected, $userConfigurationDataMapper->getConfigData($data));
+    }
+
+    /**
+     * @return array
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function getConfigDataDataProvider()
+    {
+        return [
+            'valid' =>
+            [
+                [
+                    StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
+                    StoreConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
+                    StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1/',
+                    StoreConfigurationDataMapper::KEY_CURRENCY => 'USD',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE => '1',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
+                    StoreConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
+                    StoreConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
+                    StoreConfigurationDataMapper::KEY_USE_SEF_URL => '1',
+                ],
+                [
+                    Store::XML_PATH_USE_REWRITES => '1',
+                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
+                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
+                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
+                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
+                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
+                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
+                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
+                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
+                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
+                    Url::XML_PATH_USE_SECURE_KEY => '1',
+                ],
+            ],
+            'valid alphabet url' => [
+                [
+                    StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
+                    StoreConfigurationDataMapper::KEY_BASE_URL => 'http://example.com/',
+                    StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://example.com/',
+                    StoreConfigurationDataMapper::KEY_CURRENCY => 'USD',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE => '1',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
+                    StoreConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
+                    StoreConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
+                    StoreConfigurationDataMapper::KEY_USE_SEF_URL => '1',
+                ],
+                [
+                    Store::XML_PATH_USE_REWRITES => '1',
+                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://example.com/',
+                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
+                    Store::XML_PATH_SECURE_BASE_URL => 'https://example.com/',
+                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
+                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
+                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
+                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
+                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
+                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
+                    Url::XML_PATH_USE_SECURE_KEY => '1',
+                ],
+            ],
+            'no trailing slash' =>
+            [
+                [
+                    StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
+                    StoreConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1',
+                    StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
+                    StoreConfigurationDataMapper::KEY_CURRENCY => 'USD',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE => '1',
+                    StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
+                    StoreConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
+                    StoreConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
+                    StoreConfigurationDataMapper::KEY_USE_SEF_URL => '1',
+                ],
+                [
+                    Store::XML_PATH_USE_REWRITES => '1',
+                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
+                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
+                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
+                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
+                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
+                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
+                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
+                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
+                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
+                    Url::XML_PATH_USE_SECURE_KEY => '1',
+                ],
+            ],
+            'no trailing slash, alphabet url' =>
+                [
+                    [
+                        StoreConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
+                        StoreConfigurationDataMapper::KEY_BASE_URL => 'http://example.com',
+                        StoreConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://example.com',
+                        StoreConfigurationDataMapper::KEY_CURRENCY => 'USD',
+                        StoreConfigurationDataMapper::KEY_IS_SECURE => '1',
+                        StoreConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
+                        StoreConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
+                        StoreConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
+                        StoreConfigurationDataMapper::KEY_USE_SEF_URL => '1',
+                    ],
+                    [
+                        Store::XML_PATH_USE_REWRITES => '1',
+                        Store::XML_PATH_UNSECURE_BASE_URL => 'http://example.com/',
+                        Store::XML_PATH_SECURE_IN_FRONTEND => '1',
+                        Store::XML_PATH_SECURE_BASE_URL => 'https://example.com/',
+                        Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
+                        Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
+                        Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
+                        Currency::XML_PATH_CURRENCY_BASE => 'USD',
+                        Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
+                        Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
+                        Url::XML_PATH_USE_SECURE_KEY => '1',
+                    ],
+                ],
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/UserConfigurationDataMapperTest.php b/setup/src/Magento/Setup/Test/Unit/Model/UserConfigurationDataMapperTest.php
deleted file mode 100644
index 442ee985c7c604385aa80b9993776b52110e402b..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Test/Unit/Model/UserConfigurationDataMapperTest.php
+++ /dev/null
@@ -1,236 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Test\Unit\Model;
-
-use \Magento\Setup\Model\UserConfigurationDataMapper;
-
-use Magento\Backend\Model\Url;
-use Magento\Directory\Helper\Data;
-use Magento\Directory\Model\Currency;
-use Magento\Setup\Module\Setup;
-use Magento\Store\Model\Store;
-
-class UserConfigurationDataMapperTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @param array $data
-     * @param array $expected
-     * @dataProvider getConfigDataDataProvider
-     */
-    public function testGetConfigData(array $data, array $expected)
-    {
-        $userConfigurationDataMapper = new UserConfigurationDataMapper();
-        $this->assertEquals($expected, $userConfigurationDataMapper->getConfigData($data));
-    }
-
-    /**
-     * @return array
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    public function getConfigDataDataProvider()
-    {
-        return [
-            'valid' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_CURRENCY => 'USD',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                    UserConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
-                    UserConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
-                    UserConfigurationDataMapper::KEY_USE_SEF_URL => '1',
-                ],
-                [
-                    Store::XML_PATH_USE_REWRITES => '1',
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
-                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
-                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
-                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
-                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
-                    Url::XML_PATH_USE_SECURE_KEY => '1',
-                ],
-            ],
-            'valid alphabet url' => [
-                [
-                    UserConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://example.com/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://example.com/',
-                    UserConfigurationDataMapper::KEY_CURRENCY => 'USD',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                    UserConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
-                    UserConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
-                    UserConfigurationDataMapper::KEY_USE_SEF_URL => '1',
-                ],
-                [
-                    Store::XML_PATH_USE_REWRITES => '1',
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://example.com/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://example.com/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
-                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
-                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
-                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
-                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
-                    Url::XML_PATH_USE_SECURE_KEY => '1',
-                ],
-            ],
-            'no trailing slash' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_CURRENCY => 'USD',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                    UserConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
-                    UserConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
-                    UserConfigurationDataMapper::KEY_USE_SEF_URL => '1',
-                ],
-                [
-                    Store::XML_PATH_USE_REWRITES => '1',
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                    Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
-                    Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
-                    Currency::XML_PATH_CURRENCY_BASE => 'USD',
-                    Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
-                    Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
-                    Url::XML_PATH_USE_SECURE_KEY => '1',
-                ],
-            ],
-            'no trailing slash, alphabet url' =>
-                [
-                    [
-                        UserConfigurationDataMapper::KEY_ADMIN_USE_SECURITY_KEY => '1',
-                        UserConfigurationDataMapper::KEY_BASE_URL => 'http://example.com',
-                        UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://example.com',
-                        UserConfigurationDataMapper::KEY_CURRENCY => 'USD',
-                        UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                        UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                        UserConfigurationDataMapper::KEY_LANGUAGE => 'en_US',
-                        UserConfigurationDataMapper::KEY_TIMEZONE => 'America/Chicago',
-                        UserConfigurationDataMapper::KEY_USE_SEF_URL => '1',
-                    ],
-                    [
-                        Store::XML_PATH_USE_REWRITES => '1',
-                        Store::XML_PATH_UNSECURE_BASE_URL => 'http://example.com/',
-                        Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                        Store::XML_PATH_SECURE_BASE_URL => 'https://example.com/',
-                        Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                        Data::XML_PATH_DEFAULT_LOCALE => 'en_US',
-                        Data::XML_PATH_DEFAULT_TIMEZONE => 'America/Chicago',
-                        Currency::XML_PATH_CURRENCY_BASE => 'USD',
-                        Currency::XML_PATH_CURRENCY_DEFAULT => 'USD',
-                        Currency::XML_PATH_CURRENCY_ALLOW => 'USD',
-                        Url::XML_PATH_USE_SECURE_KEY => '1',
-                    ],
-                ],
-            'is_secure, is_secure_admin set but no secure base url' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                ],
-            ],
-            'secure base url set but is_secure and is_secure_admin set to 0' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '0',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '0',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                ],
-            ],
-            'secure base url set but is_secure and is_secure_admin not set' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                ],
-            ],
-            'secure base url set, is_secure set to 0, is_secure_admin set to 1' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '0',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '0',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                ],
-            ],
-            'secure base url set, is_secure set to 1, is_secure_admin set to 0' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '0',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '0',
-                ],
-            ],
-            'secure base url set, is_secure not set, is_secure_admin set to 1' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE_ADMIN => '1',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_ADMINHTML => '1',
-                ],
-            ],
-            'secure base url set, is_secure set to 1, is_secure_admin not set' =>
-            [
-                [
-                    UserConfigurationDataMapper::KEY_BASE_URL => 'http://127.0.0.1/',
-                    UserConfigurationDataMapper::KEY_BASE_URL_SECURE => 'https://127.0.0.1',
-                    UserConfigurationDataMapper::KEY_IS_SECURE => '1',
-                ],
-                [
-                    Store::XML_PATH_UNSECURE_BASE_URL => 'http://127.0.0.1/',
-                    Store::XML_PATH_SECURE_IN_FRONTEND => '1',
-                    Store::XML_PATH_SECURE_BASE_URL => 'https://127.0.0.1/',
-                ],
-            ],
-        ];
-    }
-}
diff --git a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
index c59c2c3f1337f5a84778534329b2d97b973d595a..778c734d7e599e59722858d38fa04c110adc3fc5 100644
--- a/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Mvc/Bootstrap/InitParamListenerTest.php
@@ -29,73 +29,6 @@ class InitParamListenerTest extends \PHPUnit_Framework_TestCase
         $this->listener = new InitParamListener();
     }
 
-    public function testAttachToConsoleRoutesEmpty()
-    {
-        $inputConfig = [];
-        $expectedConfig = [];
-        $this->assertEquals(
-            $expectedConfig,
-            InitParamListener::attachToConsoleRoutes($inputConfig)
-        );
-    }
-
-    public function testAttachToConsoleRoutesOneRoute()
-    {
-        $inputConfig = [
-            'console' => ['router' => ['routes' => [['options' => ['route' => 'one_route']]]]]
-        ];
-        $expectedConfig = [
-            'console' => ['router' => ['routes' => [['options' => ['route' => 'one_route [--magento_init_params=]']]]]]
-        ];
-
-        $this->assertEquals(
-            $expectedConfig,
-            InitParamListener::attachToConsoleRoutes($inputConfig)
-        );
-    }
-
-    public function testAttachToConsoleRoutesManyRoute()
-    {
-        $inputConfig = [
-            'console' => ['router' => ['routes' => [
-                ['options' => ['route' => 'one_route']],
-                ['options' => ['route' => 'two_route']],
-                ['options' => ['route' => 'three_route']],
-                ['options' => ['route' => 'four_route']],
-                ['options' => ['route' => 'five_route']],
-            ]]]
-        ];
-        $expectedConfig = [
-            'console' => ['router' => ['routes' => [
-                ['options' => ['route' => 'one_route [--magento_init_params=]']],
-                ['options' => ['route' => 'two_route [--magento_init_params=]']],
-                ['options' => ['route' => 'three_route [--magento_init_params=]']],
-                ['options' => ['route' => 'four_route [--magento_init_params=]']],
-                ['options' => ['route' => 'five_route [--magento_init_params=]']],
-            ]]]
-        ];
-
-        $this->assertEquals(
-            $expectedConfig,
-            InitParamListener::attachToConsoleRoutes($inputConfig)
-        );
-    }
-
-    public function testGetConsoleUsage()
-    {
-        $usage = InitParamListener::getConsoleUsage();
-
-        // usage statement should be an array and have a blank line followed by a line containing the parameter
-        $this->assertArrayHasKey(0, $usage);
-        $this->assertGreaterThanOrEqual(2, count($usage));
-
-        // First element should be a blank line
-        $this->assertEquals('', $usage[0]);
-
-        // Parameter definition is added to the usage statement
-        $this->assertContains(InitParamListener::BOOTSTRAP_PARAM, implode($usage[1]));
-    }
-
     public function testAttach()
     {
         $events = $this->prepareEventManager();
diff --git a/setup/src/Magento/Setup/Test/Unit/Mvc/Console/RouteListenerTest.php b/setup/src/Magento/Setup/Test/Unit/Mvc/Console/RouteListenerTest.php
deleted file mode 100644
index 6ec5166de20f78467e738550ea2ab9feff6771c5..0000000000000000000000000000000000000000
--- a/setup/src/Magento/Setup/Test/Unit/Mvc/Console/RouteListenerTest.php
+++ /dev/null
@@ -1,163 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Setup\Test\Unit\Mvc\Console;
-
-use \Magento\Setup\Mvc\Console\RouteListener;
-
-use Zend\Mvc\MvcEvent;
-
-/**
- * Tests Magento\Setup\Mvc\Console\RouteListener
- */
-class RouteListenerTest extends \PHPUnit_Framework_TestCase
-{
-
-    /** @var RouteListener */
-    private $routeListener;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject */
-    private $request;
-
-    /** @var \PHPUnit_Framework_MockObject_MockObject */
-    private $router;
-
-    protected function setUp()
-    {
-        $this->routeListener = new RouteListener();
-        $this->request = $this->getMockBuilder('Zend\Console\Request')->disableOriginalConstructor()->getMock();
-        $this->router = $this->getMockBuilder('Zend\Mvc\Router\RouteInterface')
-            ->disableOriginalConstructor()->getMock();
-    }
-
-    public function testOnRouteHttpRequest()
-    {
-        /** @var \Zend\Mvc\MvcEvent|\PHPUnit_Framework_MockObject_MockObject $mvcEvent */
-        $mvcEvent = $this->getMockBuilder('Zend\Mvc\MvcEvent')->disableOriginalConstructor()->getMock();
-        $httpRequest = $this->getMockBuilder('Zend\Http\Request')->getMock();
-        $mvcEvent->expects($this->any())->method('getRequest')->willReturn($httpRequest);
-
-        // Sending an HttpRequest to console RouteListener should return null
-        $this->assertNull($this->routeListener->onRoute($mvcEvent));
-    }
-
-    public function testOnRouteMatch()
-    {
-        $mvcEvent = $this->prepareEvent();
-
-        $match = $this->getMockBuilder('Zend\Mvc\Router\RouteMatch')->disableOriginalConstructor()->getMock();
-        $this->router->expects($this->any())->method('match')->willReturn($match);
-        $mvcEvent->expects($this->any())->method('getRouter')->willReturn($this->router);
-
-        // There is a RouteMatch, so RouteListener will return null to trigger default listeners
-        $this->assertNull($this->routeListener->onRoute($mvcEvent));
-    }
-
-    public function testOnRouteError()
-    {
-        $mvcEvent = $this->prepareEvent();
-
-        $this->router->expects($this->any())->method('match')->willReturn(null);
-        $mvcEvent->expects($this->any())->method('getRouter')->willReturn($this->router);
-
-        $this->request->expects($this->any())->method('getContent')->willReturn([]);
-        $this->prepareOnRoute($mvcEvent, ['console' => ['router' => ['routes' => ['testAction' => 'test']]]]);
-
-        // Verify the error is set
-        $mvcEvent->expects($this->once())->method('setError');
-
-        // Should always return null
-        $this->assertNull($this->routeListener->onRoute($mvcEvent));
-    }
-
-    public function testOnRouteNoError()
-    {
-        $mvcEvent = $this->prepareEvent();
-
-        $routeMatch = $this->getMockBuilder('Zend\Mvc\Router\RouteMatch')->disableOriginalConstructor()->getMock();
-        $this->router->expects($this->any())->method('match')->willReturn($routeMatch);
-        $mvcEvent->expects($this->any())->method('getRouter')->willReturn($this->router);
-
-        // Verify the error is not set
-        $mvcEvent->expects($this->never())->method('setError');
-
-        // Should always return null
-        $this->assertNull($this->routeListener->onRoute($mvcEvent));
-    }
-
-
-    public function testOnRouteValidationMessage()
-    {
-        $mvcEvent = $this->prepareEvent();
-
-        $this->router->expects($this->any())->method('match')->willReturn(null);
-        $mvcEvent->expects($this->any())->method('getRouter')->willReturn($this->router);
-
-        $this->request->expects($this->any())->method('getContent')->willReturn(['install']);
-
-        $this->prepareOnRoute(
-            $mvcEvent,
-            ['console' => ['router' => ['routes' => ['install' => ['options' => ['route' => 'testRoute']]]]]]
-        );
-
-        // Verify the error is set
-        $mvcEvent->expects($this->once())->method('setError');
-        $mvcEvent->expects($this->once())
-            ->method('setResult')
-            ->with($this->isInstanceOf('Zend\View\Model\ConsoleModel'));
-
-        // Should always return null
-        $this->assertNull($this->routeListener->onRoute($mvcEvent));
-    }
-
-
-    public function testAttach()
-    {
-        /** @var \Zend\EventManager\EventManagerInterface|\PHPUnit_Framework_MockObject_MockObject $eventManager */
-        $eventManager = $this->getMockBuilder('Zend\EventManager\EventManagerInterface')->getMock();
-        $eventManager->expects($this->once())
-            ->method('attach')
-            ->with(
-                $this->equalTo(MvcEvent::EVENT_ROUTE),
-                $this->contains($this->routeListener),
-                10
-            );
-        $this->routeListener->attach($eventManager);
-    }
-
-    /**
-     * Create a mock MVC event with a console mock console request.
-     *
-     * @return \PHPUnit_Framework_MockObject_MockObject|MvcEvent
-     */
-    private function prepareEvent()
-    {
-        $mvcEvent = $this->getMockBuilder('Zend\Mvc\MvcEvent')->disableOriginalConstructor()->getMock();
-        $this->request = $this->getMockBuilder('Zend\Console\Request')->disableOriginalConstructor()->getMock();
-        $mvcEvent->expects($this->any())->method('getRequest')->willReturn($this->request);
-        return $mvcEvent;
-    }
-
-    /**
-     * Add a mock application, service manager and console adapter.
-     *
-     * @param \PHPUnit_Framework_MockObject_MockObject $mvcEvent
-     * @param $configArray
-     */
-    private function prepareOnRoute($mvcEvent, $configArray)
-    {
-        $application = $this->getMockBuilder('Zend\Mvc\ApplicationInterface')->getMock();
-        $serviceManager = $this->getMockBuilder('Zend\ServiceManager\ServiceLocatorInterface')->getMock();
-        $console = $this->getMockBuilder('Zend\Console\Adapter\AdapterInterface')->getMock();
-
-        $serviceManager
-            ->expects($this->any())
-            ->method('get')->will($this->returnValueMap([['Config', $configArray], ['console', $console]]));
-
-        $application->expects($this->any())->method('getServiceManager')->willReturn($serviceManager);
-        $mvcEvent->expects($this->any())->method('getApplication')->willReturn($application);
-    }
-}